将一列的熊猫操纵变为新列
问题描述:
如何将熊猫列的复杂操纵变为新列? 例如:将一列的熊猫操纵变为新列
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文件时,列表被解释为字符串。因此,另一种解决方案是以保留列表的方式保存原来的熊猫。
答
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
答
需要apply
或list 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'>