我有两个Pandas的数据框
df1
items view
0 A|B|C 02-10-2015
1 D|E 02-15-2015
df2
item num val
0 A 1 10
1 B 3 2
2 C 8 9
3 D 9 13
4 E 2 22
我想仅仅获得这些框架
df
view num1 val1 num2 val2 num3 val3
0 02-10-2015 1 10 3 2 8 9
1 02-15-2015 9 13 2 22 na na
我目前的做法是使用
拆分df1.items
df3 = pd.DataFrame(df1['items'].str.split('|').tolist())
导致
0 1 2
0 A B C
1 D E None
最后合并每个单独的列并将它们与原始df1
连接起来x = pd.merge(df3[[0]], df2, how='left', on='item')
y = pd.merge(df3[[1]], df2, how='left', on='item')
z = pd.merge(df3[[2]], df2, how='left', on='item')
pd.concat([df1, x.ix[:,1:],y.ix[:,1:],z.ix[:,1:]], axis=1)
代码有效,但对我来说似乎不对,如果有人能够指出实现相同结果的正确方法,我会很高兴。
提前谢谢!
答案 0 :(得分:4)
注意:str.split
有一个return_type
参数:
In [11]: res = df1['items'].str.split("|", return_type='frame')
In [12]: res
Out[12]:
0 1 2
0 A B C
1 D E NaN
In [13]: res.index = df1['view']
In [14]: res
Out[14]:
0 1 2
view
02-10-2015 A B C
02-15-2015 D E NaN
我认为更好,更通用的方法是使用stack / unstack:
In [15]: res = res.stack()
In [16]: res
Out[16]:
view
02-10-2015 0 A
1 B
2 C
02-15-2015 0 D
1 E
dtype: object
现在你可以合并,或者如果你很幸运,只需转出索引:
In [17]: df2 = df2.set_index('item') # could just drop this column
In [18]: df2.loc[res] # reorder, may not be required
Out[18]:
num val
item
A 1 10
B 3 2
C 8 9
D 9 13
E 2 22
现在魔术:
In [21]: df2.index = r.index
In [22]: df2
Out[22]:
num val
view
02-10-2015 0 1 10
1 3 2
2 8 9
02-15-2015 0 9 13
1 2 22
In [23]: df2.unstack()
Out[23]:
num val
0 1 2 0 1 2
view
02-10-2015 1 3 8 10 2 9
02-15-2015 9 2 NaN 13 22 NaN
根据需要(使用MultiIndex列,这是你想要的)。
注意:如果您有重复项(A,B,Cs),您将需要合并(这有点小,但可以清理)。在[21]之前:
In [31]: df2.merge(res.to_frame(), left_index=True, right_on=0).unstack()
Out[31]:
num val 0
0 1 2 0 1 2 0 1 2
view
02-10-2015 1 3 8 10 2 9 A B C
02-15-2015 9 2 NaN 13 22 NaN D E NaN