pandas сложная группировка, считай и применяй шапку - PullRequest
2 голосов
/ 23 января 2020

Пример кадра данных

> 0   location_day       payType    Name   ratePay      elapsedSeconds   
> 1   2019-12-10           PRE       Amy    12.25             199 
> 2   2019-12-12           PRE       Amy    12.25               7 
> 3   2019-12-17           PRE       Amy    12.25              68 
> 4   2019-12-17            RP       Amy     8.75              62

Для каждого дня суммируйте elapsedSeconds и вычисляйте новый столбец с общей суммой toPay (elapsedSeconds * ratePay), но применяйте «cap» elapsedSeconds, равное 120. Для любого одного дня, который имеет только 1 payType, примените кепку так, чтобы только 120 использовалось, чтобы вычислить "toPay" col.

Но ...

Кроме того, groupby payType, чтобы при наличии двух уникальных "payTypes" в один день, суммируйте elapsedSeconds, чтобы определить, превышает ли он ограничение (120), и если Итак, вычтите elapsedSeconds из последнего payType, чтобы сделать сумму равной 120.

Поэтому я хочу получить такой вывод:

> 0   location_day       payType    Name   ratePay      elapsedSeconds  
> 1   2019-12-10           PRE       Amy    12.25             120    
> 2   2019-12-12           PRE       Amy    12.25               7  
> 3   2019-12-17           PRE       Amy    12.25              68  
> 4   2019-12-17            RP       Amy     8.75              52

Я не совсем уверен, как подойти к этому и на самом деле только выполнили некоторые очень базовые c группировку и тестирование вычисления новых столбцов с условными выражениями, такими как

finDfcalc1 = finDf.sort('location_day').groupby(flds)['elapsedSeconds'].sum().reset_index()
finDfcalc1.loc[finDfcalc1['elapsedSeconds'] < 120, 'elapsedSecondsOverage'] = finDfcalc1['elapsedSeconds'] * 1
finDfcalc1.loc[finDfcalc1['elapsedSeconds'] > 120, 'elapsedSecondsOverage'] = finDfcalc1['elapsedSeconds'] - 120
finDfcalc1['toPay'] = finDfcalc1['ratePay'] * finDfcalc1['elapsedSecondsOverage']

Все это не должно быть однострочным и было бы прекрасно, если бы вы работали логи c. Все предложения и идеи с благодарностью.

1 Ответ

2 голосов
/ 23 января 2020

Нам нужно сгруппировать по дням, вычислить сумму 'elapsedSeconds', а затем применить некоторые логические значения c, чтобы обрезать итоги за день за 120 секунд, а затем вычислить обратно правильное количество # секунд для всех строк.

Вот более длинный пример набора данных, показывающий, как он ведет себя в течение дополнительного дня, с множеством строк, которые необходимо изменить.

location_day       payType    Name   ratePay      elapsedSeconds   
2019-12-10           PRE       Amy    12.25             199 
2019-12-12           PRE       Amy    12.25               7 
2019-12-17           PRE       Amy    12.25              68 
2019-12-17            RP       Amy     8.75              62
2019-12-18           PRE       Amy    12.25              50 
2019-12-18            RP       Amy     8.75              60
2019-12-18            RA       Amy     8.75              20
2019-12-18            RE       Amy     8.75              10
2019-12-18            XX       Amy     8.75              123 

Код:

# Will become the seconds you want in the end
df['real_sec'] = df.groupby('location_day').elapsedSeconds.cumsum()

# Calculate a difference
m = df['real_sec'] - df['elapsedSeconds']

                                      #MagicNum
df['real_sec'] = (df['real_sec'].clip(upper=120)   # 120 at most
                  - m.where(m.gt(0)).fillna(0)     # only change rows where diff is positive
                 ).clip(lower=0)                   # Negative results -> 0 

 location_day payType Name  ratePay  elapsedSeconds  real_sec
0   2019-12-10     PRE  Amy    12.25             199     120.0
1   2019-12-12     PRE  Amy    12.25               7       7.0
2   2019-12-17     PRE  Amy    12.25              68      68.0
3   2019-12-17      RP  Amy     8.75              62      52.0
4   2019-12-18     PRE  Amy    12.25              50      50.0
5   2019-12-18      RP  Amy     8.75              60      60.0
6   2019-12-18      RA  Amy     8.75              20      10.0
7   2019-12-18      RE  Amy     8.75              10       0.0
8   2019-12-18      XX  Amy     8.75             123       0.0
...