Комбинаторика в DataFrame с исключением Python3
Подскажите, как просуммировать столбцы названии которых уникально?
Есть df1 и df2
df1 = pd.DataFrame(data={'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8], 'C': [9, 10, 11, 12], 'D': [13, 14, 15, 16], 'E': [17, 18, 19, 20], 'F': [21, 22, 23, 24], 'G': [25, 26, 27, 28], 'H': [29, 30, 31, 32], 'L': [33, 34, 35, 36], 'K': [37, 38, 39, 40], 'M': [41, 42, 43, 44], 'P': [45, 46, 47, 48]})
df2 = pd.DataFrame(data={'A': [254, 223, 335,222], 'B': [545, 667, 743, 856], 'D': [986, 104, 113, 124], 'E': [137, 149, 165, 176]})
на этом шаге в df1 провожу суммирование столбцов и получаю df_summ все хорошо.
my_list=[(pd.Series(df1.loc[:,list(i)].sum(axis=1), name='_'.join(df1.loc[:,list(i)].columns))) for i in list(itertools.combinations(df1.columns,2))]
df_summ=pd.concat(my_list,axis=1)
print(df_summ)
A_B A_C A_D A_E A_F A_G A_H ... H_P L_K L_M L_P K_M K_P M_P
0 6 10 14 18 22 26 30 ... 74 70 74 78 78 82 86
1 8 12 16 20 24 28 32 ... 76 72 76 80 80 84 88
2 10 14 18 22 26 30 34 ... 78 74 78 82 82 86 90
3 12 16 20 24 28 32 36 ... 80 76 80 84 84 88 92
[4 rows x 66 columns]
Вот тут вопрос, как просуммировать df_summ и df2, так что бы суммировались столбцы уникальные. Вроде как эту функцию itertools.product можно применить.
Примерно должно получиться так:
A_B+D A_C+D A_D+B A_E+B A_F+B A_G+B A_H+B
0 992 996 559 563 567 571 575
1 112 116 683 687 691 695 699
2 123 127 761 765 769 773 777
3 136 140 876 880 884 888 892
Ответы (1 шт):
Если я правильно понял, то можно сделать так:
Исходные:
df1 = pd.DataFrame(data={'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8], 'C': [9, 10, 11, 12], 'D': [13, 14, 15, 16], 'E': [17, 18, 19, 20], 'F': [21, 22, 23, 24], 'G': [25, 26, 27, 28], 'H': [29, 30, 31, 32], 'L': [33, 34, 35, 36], 'K': [37, 38, 39, 40], 'M': [41, 42, 43, 44], 'P': [45, 46, 47, 48]})
df2 = pd.DataFrame(data={'A': [254, 223, 335,222], 'B': [545, 667, 743, 856], 'D': [986, 104, 113, 124], 'E': [137, 149, 165, 176]})
Сразу получаем список столбцов, общий для обоих фреймов, проводим конкатенацию и делаем красивые имена столбцов:
df1_cols = list(itertools.combinations(df1.columns,2))
cols = [x+tuple(y) for x in df1_cols for y in df2.columns.to_list() if y not in x]
res = pd.concat([df1[c[0]].add(df1[c[1]].add(df2[c[2]])) for c in cols], axis=1, keys=cols)
res.columns = ['_'.join(x) for x in res.columns.values]
получаем res:
A_B_D A_B_E A_C_B A_C_D A_C_E A_D_B A_D_E A_E_B A_E_D A_F_B ... \
0 992 143 555 996 147 559 151 563 1004 567 ...
1 112 157 679 116 161 683 165 687 124 691 ...
2 123 175 757 127 179 761 183 765 135 769 ...
3 136 188 872 140 192 876 196 880 148 884 ...
K_M_D K_M_E K_P_A K_P_B K_P_D K_P_E M_P_A M_P_B M_P_D M_P_E
0 1064 215 336 627 1068 219 340 631 1072 223
1 184 229 307 751 188 233 311 755 192 237
2 195 247 421 829 199 251 425 833 203 255
3 208 260 310 944 212 264 314 948 216 268
UPDATE
Если нужно получить промежуточный фрейм df_summ, то можно сделать так:
my_list=[(pd.Series(df1.loc[:,list(i)].sum(axis=1), name='_'.join(df1.loc[:,list(i)].columns))) for i in list(itertools.combinations(df1.columns,2))]
df_summ=pd.concat(my_list,axis=1)
Соответственно, df_summ получится:
A_B A_C A_D A_E A_F A_G A_H A_L A_K A_M ... H_L H_K H_M H_P \
0 6 10 14 18 22 26 30 34 38 42 ... 62 66 70 74
1 8 12 16 20 24 28 32 36 40 44 ... 64 68 72 76
2 10 14 18 22 26 30 34 38 42 46 ... 66 70 74 78
3 12 16 20 24 28 32 36 40 44 48 ... 68 72 76 80
L_K L_M L_P K_M K_P M_P
0 70 74 78 78 82 86
1 72 76 80 80 84 88
2 74 78 82 82 86 90
3 76 80 84 84 88 92
А затем придётся городить такой огород:
cols = [x+tuple(y) for x in [tuple(c.split("_")) for c in df_summ.columns.to_list()] for y in df2.columns.to_list() if y not in x]
res = pd.concat([df_summ[f"{c[0]}_{c[1]}"].add(df2[c[2]]) for c in cols], axis=1, keys=cols)
res.columns = [f"{x[0]}_{x[1]}+{x[2]}" for x in res.columns.values]
Ну и res, соответственно:
A_B+D A_B+E A_C+B A_C+D A_C+E A_D+B A_D+E A_E+B A_E+D A_F+B ... \
0 992 143 555 996 147 559 151 563 1004 567 ...
1 112 157 679 116 161 683 165 687 124 691 ...
2 123 175 757 127 179 761 183 765 135 769 ...
3 136 188 872 140 192 876 196 880 148 884 ...
K_M+D K_M+E K_P+A K_P+B K_P+D K_P+E M_P+A M_P+B M_P+D M_P+E
0 1064 215 336 627 1068 219 340 631 1072 223
1 184 229 307 751 188 233 311 755 192 237
2 195 247 421 829 199 251 425 833 203 255
3 208 260 310 944 212 264 314 948 216 268