列比较&列复制

时间:2014-12-11 21:08:08

标签: python pandas dataframe

我有两个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

有人能想到一个简洁的大熊猫解决这个问题吗?

3 个答案:

答案 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