2017-05-31 52 views
2

我有pandas.DataFrame(...)以下面的格式(工作实施例):分解具有多个值的细胞在一个数据帧

df = pd.DataFrame({'foo1':[1,2,3], 'foo2': ["a:1, b:2", "d:4", "a:6, d:5"]}) 
df 
    foo1  foo2 
0  1 a:1, b:2 
1  2  d:4 
2  3 a:6, d:5 

我想到foo2单元值分解成列(O/P DF):

foo1  foo2_a foo2_b foo2_d 
0  1   1   2   0 
1  2   0   0   4 
2  3   6   0   5 

我可以遍历整个数据帧通过索引,每行的存储值 - 但它似乎不是elegent。

是否有一些pandas技巧/ elegent/pythonic解决这个问题? 谢谢!

回答

1

如果使用

df.foo2.str.split(', ').apply(lambda l: pd.Series({e.split(':')[0]: int(e.split(':')[1]) for e in l})).fillna(0) 

你得到

 a b d 
0 1.0 2.0 0.0 
1 0.0 0.0 4.0 
2 6.0 0.0 5.0 

注意,一旦你的每一行成一个字典,你可以将它变成一个熊猫Series,这将是这个结果。

从这一点来看,这只是一个重命名列的问题,并且concat表示输入结果。

1

使用split + applylist comprehension对于dicts。然后通过values + tolistadd_prefix和最后joinfoo1转换列numpy array

s = df['foo2'].str.split(', ').apply(lambda x: dict([y.split(':') for y in x])) 
df1 = pd.DataFrame(s.values.tolist()).fillna(0).add_prefix('foo2_').astype(int) 
df = df[['foo1']].join(df1) 
print (df) 
    foo1 foo2_a foo2_b foo2_d 
0  1  1  2  0 
1  2  0  0  4 
2  3  6  0  5 
+0

一些问题?如果是的话,你能解释一下吗? – jezrael

1
#find all the keys ('a','b','d',...) 
d = {k:0 for k in df.foo2.str.extractall('([a-z]+)(?=:)').iloc[:,0].unique()} 
#split foo2 and build a new DF then merge it into the existing DF. 
pd.concat([df['foo1'].to_frame(), df.foo2.str.split(', ')\ 
    .apply(lambda x: pd.Series(dict(d,**dict([e.split(':') for e in x])))).add_prefix('foo2_')], axis=1) 

Out[149]: 
    foo1 foo2_a foo2_b foo2_d 
0  1  1  2  0 
1  2  0  0  4 
2  3  6  0  5 
相关问题