5

Без параллельного программирования я могу слить левый и правый данные на столбце key, используя приведенный ниже код, но он будет слишком медленным, так как оба очень большие. есть ли способ, которым я могу это сделать, эффективно распараллеливать?Как объединить две части данных pandas параллельно (многопоточность или многопроцессорность)

У меня 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 

Я хочу сделать это параллельно, так что я могу сделать это на скорости.

+0

Даже если решение «многопоточность» возможно, вам придется разбить свои dataframes на куски, объединить их параллельно (возможно, с использованием 'многопоточность 'module), а затем объединить куски. Все это только улучшит вашу скорость в 4 раза (учитывая, что у вас есть 4 ядра) ... –

+0

У меня 64 ядра, и поэтому практически я могу использовать 63 из них, чтобы объединить эти два блока данных. – contactlp

ответ

3

Вы можете улучшить скорость (примерно в 3 раза по данному примеру) вашего слияния, сделав столбец индексом ваших данных и используя вместо этого join.

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 
+2

спасибо, я также включил это также, но у меня есть 64 ядра, я хочу их использовать. – contactlp

5

Я считаю, вы можете использовать dask. и функция merge.

Docs говорят:

Что определенно работает?

Умело параллелизуемые операции (также быстро):

Регистрация на индекс: dd.merge (df1, df2, left_index = True, right_index = True)

Или:

Операции, требующие перетасовки (замедленное, если не указано)

Индекс

Set: df.set_index (df.x)

Регистрация не по индексу: pd.merge (df1, df2, на 'имя' =)

Вы также можете проверьте, как Create 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 
Смежные вопросы