在DataFrame

时间:2017-05-31 11:39:48

标签: python pandas dataframe

我的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

我可以通过索引遍历整个数据框,每行存储值 - 但它看起来并不优雅。

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

3 个答案:

答案 0 :(得分: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

请注意,一旦将每行放入字典中,就可以将其转换为pandas Series,这就是结果。

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

答案 1 :(得分:1)

split + applylist comprehension一起用于dicts。然后按values + tolistadd_prefix和最后joinnumpy array将列转换为foo1

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

答案 2 :(得分: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