合并仅部分匹配的列上的DataFrame

时间:2019-11-08 08:48:00

标签: python pandas

我有两个具有以下结构的大型DataFrame(每行1m-5m行):

DF1                         DF2
    id          value           id    value
0   0000_alpha  100         0   0000  100
1   0000_beta   200         1   0001  200
2   0000_gamma  300         2   0002  300
3   0001_alpha  150         3   0003  400
4   0001_beta   250         4   0004  500
5   0001_gamma  350         5   0005  600
    ....                        ....

我想将DF1中ID的数字匹配但字母不匹配的值的总和加到DF2中ID相同的数字中。所以最终结果将是:

DF3
    id     value
0   0000   700
1   0001   950
    ....

我似乎无法弄清楚如何以最佳方式合并部分匹配ID上的两个DataFrame(注意:每个ID中的数字和字母的数量不一致。例如:一个ID可能是0000_alpha,而另一个是4858394_gamma)。

我有以下代码可以正常工作,但是运行时间太长,因为它正在对大型DataFrame之一进行迭代。

for k,v in DF2.iterrows():
    v['value'] += DF1['value'].loc[DF1.id.str.contains(str(v.id))].sum()

任何有关如何改进上述代码,在pd.mergepd.groupby中进行部分匹配的建议,或任何其他建议,都欢迎。

1 个答案:

答案 0 :(得分:2)

您可以使用str.findallstr.split,具体取决于id列的方式。

df = pd.DataFrame({'id': {0: '0000_alpha', 1: '0000_beta', 2: '0000_gamma', 3: '0001_alpha', 4: '0001_beta', 5: '0001_gamma'},
                   'value': {0: 100, 1: 200, 2: 300, 3: 150, 4: 250, 5: 350}})

df2 = pd.DataFrame({'id': {0: "0000", 1: "0001", 2: "0002", 3: "0003", 4: "0004", 5: "0005"},
                    'value': {0: 100, 1: 200, 2: 300, 3: 400, 4: 500, 5: 600}})

方法1 :使用str.findall

print (pd.merge(df.groupby([df["id"].str.findall("\d+").str[0]]).sum(), df2, on=["id"], how="right").set_index(['id']).sum(axis=1))

#
id
0000    700.0
0001    950.0
0002    300.0
0003    400.0
0004    500.0
0005    600.0

方法2 :使用str.split

print (pd.merge(df.groupby([df["id"].str.split("_").str[0]]).sum(), df2, on=["id"], how="right").set_index(['id']).sum(axis=1))

#
id
0000    700.0
0001    950.0
0002    300.0
0003    400.0
0004    500.0
0005    600.0