Python DataFrame:将键列表的一列映射到值列表的一列
以下是输入:Python DataFrame:将键列表的一列映射到值列表的一列,python,pandas,dataframe,Python,Pandas,Dataframe,以下是输入: df = pd.DataFrame({'keys': [('K0', 'K1'), ('K1', 'K2')], 'A': ['A0', 'A1']}) lookup_df = pd.DataFrame({'val': ['V1', 'V2', 'V3']}, index = ['K0', 'K1', 'K2']) 在一些“join”操作之后,我希望在df中添加一个新列,它将df中的ke
df = pd.DataFrame({'keys': [('K0', 'K1'), ('K1', 'K2')],
'A': ['A0', 'A1']})
lookup_df = pd.DataFrame({'val': ['V1', 'V2', 'V3']},
index = ['K0', 'K1', 'K2'])
在一些“join”操作之后,我希望在df
中添加一个新列,它将df
中的keys
映射到lookup\u df
中的val
输出应为:
pd.DataFrame({'keys': [('K0', 'K1'), ('K1', 'K2')],
'val': [('V0', 'V1'), ('V1', 'V2')],
'A': ['A0', 'A1']})
我能想到的一个方法是:
df['val'] = df['keys'].apply(lambda ks:
list(map(lambda k: lookup_df.loc[k].val, ks)))
还有其他更好的方法吗?您可以这样做:
In [83]: df['val'] = df['keys'].str.join(',').str.split(',', expand=True).stack().map(lookup_df.val).unstack().apply(tuple)
In [84]: df
Out[84]:
A keys val
0 A0 (K0, K1) (V1, V2)
1 A1 (K1, K2) (V2, V3)
In [85]: lookup_df
Out[85]:
val
K0 V1
K1 V2
K2 V3
或者更好,但速度较慢的方法(由于):
针对10K行DF的计时:
In [18]: big = pd.concat([df] * 10**5, ignore_index=True)
In [19]: x = big.head(10**4)
In [20]: x.shape
Out[20]: (10000, 2)
In [21]: %timeit x['keys'].str.join(',').str.split(',', expand=True).stack().map(lookup_df.val).unstack().apply(tuple)
10 loops, best of 3: 75.1 ms per loop
In [22]: %timeit x['keys'].apply(pd.Series).stack().map(lookup_df.val).unstack().apply(tuple)
1 loop, best of 3: 5.5 s per loop
In [23]: %timeit x['keys'].apply(pd.Series).replace(lookup_df.val).apply(tuple)
1 loop, best of 3: 5.52 s per loop
In [24]: %%timeit
....: dk = pd.DataFrame(x['keys'].tolist()).applymap(lambda x: lookup_df.val[x])
....: x['val'] = zip(dk[0], dk[1])
....:
1 loop, best of 3: 1.66 s per loop
结论:最丑陋的方法是目前最快的方法更短并避免字符串操纵:
df['val'] = df['keys'].apply(pd.Series).replace(lookup_df.val).apply(tuple)
这并不意味着漂亮
dk = pd.DataFrame(df['keys'].tolist()).applymap(lambda x: lookup_df.val[x])
df['val'] = zip(dk[0], dk[1])
df
你不想用
df['keys']开始rubikscus吗。应用(pd.Series)
而不是你的join/split
?除非我弄错了,。应用(tuple)
应该是。应用(tuple,1)
。由于数据帧的对称性,将默认轴保留为0只会同时起作用。
dk = pd.DataFrame(df['keys'].tolist()).applymap(lambda x: lookup_df.val[x])
df['val'] = zip(dk[0], dk[1])
df