我有两个DataFrame, df1 和 df2 :
>>> import pandas as pd
>>> df1 = pd.DataFrame(data={'pkid': [1, 2], 'files': ['f1', 'f2']})
>>> df1
files pkid
0 f1 1
1 f2 2
>>> df2 = pd.DataFrame(data={'records': [1, 2, 3, 4, 5, 6], 'files': ['f1', 'f1', 'f2', 'f1', 'f2', 'f2']})
>>> df2
files records
0 f1 1
1 f1 2
2 f2 3
3 f1 4
4 f2 5
5 f2 6
我希望在 df2 中创建名为 files_fkid 的第三列。
我想要一个解决方案,其中 df1 的文件列与 df2 中的文件列进行比较, df1 各自< strong> pkid 放置在 df2 的新 files_fkid 列中。所以新的 df2 将打印为:
>>> df2
files records files_fkid
0 f1 1 1
1 f1 2 1
2 f2 3 2
3 f1 4 1
4 f2 5 2
5 f2 6 2
有人能想到一个简洁的大熊猫解决这个问题吗?
答案 0 :(得分:3)
比@ ajcr更快的方法是在这里使用map
因为你有一个唯一的索引然后这比调用apply更快,这实际上是一个for循环:
In [15]:
df1_ = df1.set_index('files')
%timeit df2['files_fkid'] = df2['files'].map(df1_['pkid'])
df2
1000 loops, best of 3: 636 µs per loop
Out[15]:
files records files_fkid
0 f1 1 1
1 f1 2 1
2 f2 3 2
3 f1 4 1
4 f2 5 2
5 f2 6 2
In [17]:
df1_ = df1.set_index('files')
%timeit df2['files_fkid'] = df2.files.apply(lambda x: df1_.loc[x])
df2
100 loops, best of 3: 2.61 ms per loop
Out[17]:
files records files_fkid
0 f1 1 1
1 f1 2 1
2 f2 3 2
3 f1 4 1
4 f2 5 2
5 f2 6 2
所以你看到它已经快了4倍并且会扩展得更好。如果你将一个系列或dict作为一种查找形式传递给map作为参数,如果索引是唯一的(在这种情况下它是,并且键必须是dict的唯一),那么查找将非常快。
答案 1 :(得分:2)
您可以使用pd.merge:
import numpy as np
import pandas as pd
df1 = pd.DataFrame(data={'pkid': [1, 2], 'files': ['f1', 'f2']})
df2 = pd.DataFrame(data={'records': [1, 2, 3, 4, 5, 6]
, 'files': ['f1', 'f1', 'f2', 'f1', 'f2', 'f2']})
result = pd.merge(
df2
, df1.rename(columns={'pkid' : 'files_fkid'})
, on=['files'], how='outer').sort(['records'])
产量
files records files_fkid
0 f1 1 1
1 f1 2 1
3 f2 3 2
2 f1 4 1
4 f2 5 2
5 f2 6 2
答案 2 :(得分:1)
您可以将files
设置为df1
中的索引,然后应用使用loc
的函数来查找与索引对应的pkid
值:
>>> df1_ = df1.set_index('files')
>>> df2['files_fkid'] = df2.files.apply(lambda x: df1_.loc[x])
>>> df2
files records files_fkid
0 f1 1 1
1 f1 2 1
2 f2 3 2
3 f1 4 1
4 f2 5 2
5 f2 6 2