熊猫操纵一列成新栏目

问题描述 投票:3回答:2

如何将熊猫柱的复杂操作变为新列?例如:

import pandas as pd
import ast

d = {'col1' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 
     'col2' : pd.Series(['[9, 10]', '[10, 11]', '[11, 12]', '[12,13]'],
              index=['a', 'b', 'c', 'd'])
    }
df = pd.DataFrame(d)
print(df)

所以最后一列实际上是一个字符串,但我想将其转换为列表。

我试过了:

df['new'] = ast.literal_eval(df['col2')

这会引发错误。

我已经尝试了很多其他的东西,无法得到任何工作。

我想还有另一种方法来回答这个问题:

在之前的文件中,我创建了我的df,列表是列的元素,然后保存到csv。当我打开csv文件时,列表被解释为字符串。因此,另一种解决方案是以保留列表的方式保存原始熊猫。

python pandas
2个回答
3
投票

json.loads的作用是因为你的名单是有效的json。您可以使用已在json中导入的pandas

df.assign(new=df.col2.apply(pd.io.json.loads))

   col1      col2       new
a     1   [9, 10]   [9, 10]
b     2  [10, 11]  [10, 11]
c     3  [11, 12]  [11, 12]
d     4   [12,13]  [12, 13]

print(type(df.assign(new=df.col2.apply(pd.io.json.loads)).iloc[0, -1]))

<class 'list'>

无论出于何种原因,json解析似乎比literal_eval更快

%timeit df.assign(new=df.col2.apply(pd.io.json.loads))
%timeit df.assign(new=df.col2.apply(literal_eval))
%timeit df.assign(new=[ast.literal_eval(x) for x in df['col2']])

小数据

1000 loops, best of 3: 410 µs per loop
1000 loops, best of 3: 468 µs per loop
1000 loops, best of 3: 397 µs per loop

大数据

df = pd.concat([df] * 10000, ignore_index=True)

100 loops, best of 3: 17.9 ms per loop
1 loop, best of 3: 333 ms per loop
1 loop, best of 3: 331 ms per loop

2
投票

需要applylist comprehension

import ast
df['new'] = df['col2'].apply(ast.literal_eval)

df['new'] = [ast.literal_eval(x) for x in df['col2']]

print(type(df.loc['a', 'new']))
<class 'list'>
© www.soinside.com 2019 - 2024. All rights reserved.