Векторизация попарного столбчатого элемента в NumPy - PullRequest
4 голосов
/ 06 ноября 2019

У меня есть два DataFrames:

>>> d1

    A  B
0   4  3
1   5  2
2   4  3

>>> d2

    C  D  E
0   1  4  7
1   2  5  8
2   3  6  9

>>> what_I_want

    AC  AD  AE  BC  BD  BE
0   4   16  28  3   12  21
1   10  25  40  4   10  16
2   12  24  36  9   18  27

Два DataFrames имеют одинаковое количество строк (скажем, m), но разное количество столбцов (скажем, ncol_1, ncol_2). Вывод осуществляется через (ncol_1 * ncol_2) DataFrame. Каждый столбец является произведением одного столбца в d1 и одного столбца в d2.

Я сталкивался с np.kron, но это не совсем то, что я хочу. Мои реальные данные содержат миллионы строк.

Мне интересно, есть ли какой-нибудь векторизованный способ сделать это? В настоящее время у меня есть реализация itertools.product, но скорость мучительно медленная.

Ответы [ 2 ]

8 голосов
/ 06 ноября 2019

Один с NumPy-broadcasting -

a = d1.to_numpy(copy=False) # d1.values on older pandas versions
b = d2.to_numpy(copy=False)
df_out = pd.DataFrame((a[:,:,None]*b[:,None,:]).reshape(len(a),-1))
df_out.columns = [i+j for i in d1.columns for j in d2.columns]

Для больших данных используйте multi-cores с numexpr -

import numexpr as ne

out = ne.evaluate('a3D*b3D',{'a3D':a[:,:,None],'b3D':b[:,None]}).reshape(len(a),-1)
df_out = pd.DataFrame(out)
3 голосов
/ 06 ноября 2019

IIUC, использование для цикла не всегда плохо, проверка

pd.DataFrame({x+y: df1[x]*df2[y]  for x in df1 for y in df2})
Out[81]: 
   AC  AD  AE  BC  BD  BE
0   4  16  28   3  12  21
1  10  25  40   4  10  16
2  12  24  36   9  18  27
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...