比较两个大小不同的Pandas数据框架

9

我有一个巨大的Pandas数据框,结构如下:

df1:
    A   B
0   0  12
1   0  15
2   0  17
3   0  18
4   1  45
5   1  78
6   1  96
7   1  32
8   2  45
9   2  78
10  2  44
11  2  10

还有一个小一点的,像这样:

df2
   G   H
0  0  15
1  1  45
2  2  31

我想按照以下规则向我的第一个数据框添加一列:当df1.A == df2.G时,列df1.C = df2.H

我设法用for循环实现了它,但是数据库非常庞大,代码运行得非常慢,所以我正在寻找Pandas或numpy的解决方法。

非常感谢,

Boris


那么,df2.G 中的所有元素都保证在 df1.A 中吗?df2.G 是否已排序?您实际使用情况下输入数据框的形状是什么? - Divakar
输入数据包含更多的列/行,但结构相同。我需要的函数是 DataFrame.merge(),它完美地工作。 - boris
4个回答

4

您可以通过由set_index创建的Series来使用map

df1['C'] = df1['A'].map(df2.set_index('G')['H'])
print (df1)
    A   B   C
0   0  12  15
1   0  15  15
2   0  17  15
3   0  18  15
4   1  45  45
5   1  78  45
6   1  96  45
7   1  32  45
8   2  45  31
9   2  78  31
10  2  44  31
11  2  10  31

使用 mergedroprename

df = df1.merge(df2,left_on="A",right_on="G", how='left')
        .drop('G', axis=1)
        .rename(columns={'H':'C'})
print (df)
    A   B   C
0   0  12  15
1   0  15  15
2   0  17  15
3   0  18  15
4   1  45  45
5   1  78  45
6   1  96  45
7   1  32  45
8   2  45  31
9   2  78  31
10  2  44  31
11  2  10  31

4

如果你只想匹配两个数据帧中的相同行:

import pandas as pd

df1 = pd.DataFrame({'Name':['Sara'],'Special ability':['Walk on water']})
df1    
   Name Special ability
0  Sara   Walk on water

df2 = pd.DataFrame({'Name':['Sara', 'Gustaf', 'Patrik'],'Age':[4,12,11]})
df2
     Name  Age
0    Sara    4
1  Gustaf   12
2  Patrik   11

df = df2.merge(df1, left_on='Name', right_on='Name', how='left')
df
     Name  Age Special ability
0    Sara    4             NaN
1  Gustaf   12   Walk on water
2  Patrik   11             NaN

多个匹配参数也可以完成此操作: (在此示例中,因为两个数据框中的年龄不同,所以df1中的Patrik不存在于df2中,不会合并)

df1 = pd.DataFrame({'Name':['Sara','Patrik'],'Special ability':['Walk on water','FireBalls'],'Age':[12,83]})

df1
     Name Special ability  Age
0    Sara   Walk on water   12
1  Patrik       FireBalls   83

df2 = pd.DataFrame({'Name':['Sara', 'Gustaf', 'Patrik'],'Age':[4,12,11]})
df2
     Name  Age
0    Sara    4
1  Gustaf   12
2  Patrik   11

df = df2.merge(df1,left_on=['Name','Age'],right_on=['Name','Age'],how='left')
df
     Name  Age Special ability
0    Sara   12   Walk on water
1  Gustaf   12             NaN
2  Patrik   11             NaN

2
您可能需要使用合并操作:
df=df1.merge(df2,left_on="A",right_on="G")

这将会给你一个包含3个列的数据框,但第三列的名称将会是H。

df.columns=["A","B","C"]

它会给你想要的列名


0
这是一个向量化的NumPy方法 -
idx = np.searchsorted(df2.G.values, df1.A.values)
df1['C'] = df2.H.values[idx]

idx 可以通过以下更简单的方式计算:df2.G.searchsorted(df1.A),但是不认为这样会更有效率,因为我们想要像之前一样使用 .values 的底层数组来提高性能。


@boris 请确保在您的端计时。应该非常高效 :) - Divakar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接