#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 секунды. Красивые. Спасибо!