如何并行合并两个pandas数据框(使用多线程或多进程)

13

在不进行并行编程的情况下,我可以使用以下代码将左右数据帧合并在key列上,但由于两个数据帧都非常大,这将太慢了。有没有一种方法可以高效地并行化处理?

我有64个核心,因此实际上我可以使用其中63个来合并这两个数据帧。

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})


right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})


result = pd.merge(left, right, on='key')

输出结果将是:

left:
    A   B key
0  A0  B0  K0
1  A1  B1  K1
2  A2  B2  K2
3  A3  B3  K3

right:
    C   D key
0  C0  D0  K0
1  C1  D1  K1
2  C2  D2  K2
3  C3  D3  K3

result:
    A   B key   C   D
0  A0  B0  K0  C0  D0
1  A1  B1  K1  C1  D1
2  A2  B2  K2  C2  D2
3  A3  B3  K3  C3  D3

我希望以并行方式完成这项工作,这样可以更快地完成。


即使“多线程”解决方案是可行的,您也必须将数据框架分成块,在并行中合并它们(可能使用“线程”模块),然后将块放回到一起。所有这些仅会将速度提高>4倍(假设您有4个核心)... - Gustavo Bezerra
我有64个核心,所以实际上我可以使用其中63个来合并这两个数据框。 - Lav Patel
2个回答

14

我相信您可以使用 dask 和函数 merge

文档称:

什么肯定有效?

巧妙可并行操作(也快):

按索引合并:dd.merge(df1, df2, left_index=True, right_index=True)

或者:

需要洗牌的操作(除非在索引上,否则较慢)

设置索引:df.set_index(df.x)

不基于索引的合并:pd.merge(df1, df2, on='name')

您还可以查看如何创建Dask DataFrames

示例

import pandas as pd

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})


right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})


result = pd.merge(left, right, on='key')
print result
    A   B key   C   D
0  A0  B0  K0  C0  D0
1  A1  B1  K1  C1  D1
2  A2  B2  K2  C2  D2
3  A3  B3  K3  C3  D3

import dask.dataframe as dd

#Construct a dask objects from a pandas objects
left1 = dd.from_pandas(left, npartitions=3)
right1 = dd.from_pandas(right, npartitions=3)

#merge on key
print dd.merge(left1, right1, on='key').compute()
    A   B key   C   D
0  A3  B3  K3  C3  D3
1  A1  B1  K1  C1  D1
0  A2  B2  K2  C2  D2
1  A0  B0  K0  C0  D0
#first set indexes and then merge by them
print dd.merge(left1.set_index('key').compute(), 
               right1.set_index('key').compute(), 
               left_index=True, 
               right_index=True)
      A   B   C   D
key                
K0   A0  B0  C0  D0
K1   A1  B1  C1  D1
K2   A2  B2  C2  D2
K3   A3  B3  C3  D3

6

您可以通过将数据框的key列设置为索引,并使用join代替,来提高合并速度(在给定示例中大约提高了3倍)。

left2 = left.set_index('key')
right2 = right.set_index('key')

In [46]: %timeit result2 = left2.join(right2)
1000 loops, best of 3: 361 µs per loop

In [47]: %timeit result = pd.merge(left, right, on='key')
1000 loops, best of 3: 1.01 ms per loop

1
这很不错,但是如果要在几个“keys”上进行合并,使用“join”仍然可以吗?例如:pd.merge(left, right, on=['key1','key2'] - Lucas Aimaretto

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