我的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解决方案?
谢谢!
答案 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
+ apply
与list comprehension
一起用于dicts
。然后按values
+ tolist
,add_prefix
和最后join
列numpy 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