Продукты из столбцов в пустой фрейм

#python #pandas #dataframe

#python #панды #фрейм данных

Вопрос:

У меня есть два фрейма. frame_1 является пустым и содержит уникальный Sample столбец, соответствующий Sample столбцу в frame_2 . Я хочу frame_1 заполнить продукты, рассчитанные на frame_2 основе Sample столбца, а затем создать Max_prod столбец. val_ , val_2 , val_3 , prod_1 , prod_2 , prod_3 , и Max_prod столбцы имеют тип float .

Фреймы выглядят так:

frame_1 перед вычислением продуктов

 ID    Sample    prod_1    prod_2    prod_3    Max_prod
0     1         
1     2         
 

frame_2

 ID    Sample    val_1    val_2    val_3  
0     1         1        2        2               
1     1         2        2        2               
2     1         7500     2        7500
3     1         1        1        1
4     1         1        1        1
5     1         1        2500     1
6     1         1        1        1
7     1         1        1        1
8     1         1        1        1
9     1         2        1        1
10    1         1        1        1
11    1         1        1        1
12    1         2        1        1
13    1         1        1        1
14    1         1        1        1
15    1         1        1        1
16    1         2        1        1
17    1         1        1        1
18    1         1        1        1
19    1         1        1        1
20    1         1        1        1
21    2         2        2        2
22    2         3        3        3
23    2         1        1        1
24    2         1        1        1
25    2         1        333.333  1
26    2         1        1        1
27    2         1        1        1
28    2         1        1        1
29    2         1        1        1
30    2         1        1        1
31    2         1        5        370.3704
32    2         5000     4        1
33    2         1        1        1
34    2         1        1        1
35    2         1        1        9
36    2         1        1        1
37    2         1        1        1
38    2         1        1        1
39    2         1        1        1
40    2         1        1        1
41    2         1        1        1
 

вывод для frame_1 ——> заполненный

 ID    Sample    prod_1   prod_2   prod_3   Max_prod
0     1         120000   20000    30000    120000
1     2         30000    40000    20000    40000
 

Мой код делает то, что мне нужно, но проблема в том, что когда я расширяю его, скажем Sample frame_1 , до 100 000 в столбце (т. Е. До Sample frame_2 21 000 000 в столбце), это занимает около десяти минут. Это нормально, но было бы лучше, если бы я мог ускорить это. Какое-то объединение? У кого-нибудь есть идеи?

 for sample in frame_1['Sample']:
    mask1 = (sample == frame_1['Sample'])
    mask2 = (sample  == frame_2['Sample'])
    frame_1.loc[mask1, 'prod_1'] = frame_2.loc[mask2, 'val_1'].prod()
    frame_1.loc[mask1, 'prod_2'] = frame_2.loc[mask2, 'val_2'].prod()
    frame_1.loc[mask1, 'prod_3'] = frame_2.loc[mask2, 'val_3'].prod()
frame_1['Max_prod'] = frame1[['val_1', 'val_2','val_3']].max(axis=1)
 

Ответ №1:

Чтобы получить произведение val_X per Sample , попробуйте groupby и aggregation .

 frame_1 = frame_2.groupby('Sample') 
    .agg({'val_1':'prod', 'val_2': 'prod', 'val_3': 'prod'}) 
    .reset_index()
 

Для Pandas > = 0.25

Вы можете назвать агрегацию.

 frame_1 = frame_2.groupby('Sample') 
    .agg(prod_1=('val_1','prod'), prod_2=('val_2', 'prod'), prod_3=('val_3', 'prod')) 
    .reset_index()
 

Как правило, вы хотите избежать for цикла для работы pandas. функции pandas векторизованы, поэтому вы можете повысить их производительность.

Комментарии:

1. Спасибо. Я знаю, я просто не был уверен, как векторизовать получение таких продуктов, когда мне приходилось делать все из них. Я попробую это.

2. Я думаю, что это будет работать очень хорошо. Я отмечу это, как только я запущу его на 100k. Попробовал это на 10, и это было намного быстрее, чем даже 5k с циклом for

3. 10 минут до 1,4 секунды. Красивые. Спасибо!