2017-06-22 49 views
3

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

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文件时,列表被解释为字符串。因此,另一种解决方案是以保留列表的方式保存原来的熊猫。

回答

3

json.loads作品,因为你的列表是有效json。您可以使用jsonpandas

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'>