Как рассчитать обратную сумму в пандах - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь найти способ вычислить обратное значение для панд. Это означает применение cumsum, но снизу вверх. Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь найти количество рабочих дней для каждого месяца в Испании как сверху вниз (1-й рабочий день = 1, 2-й = 2, 3-й = 3 и т. Д.), Так иснизу вверх (последний рабочий день = 1, предыдущий день = 2 и т. д.). До сих пор мне удавалось заставить работать порядок сверху вниз, но я не могу заставить работать обратный порядок, я много искал и не мог найти способ выполнить обратную кумулятивную сумму:

import pandas as pd
from datetime import date
from workalendar.europe import Spain
import numpy as np
cal = Spain()
#print(cal.holidays(2019))
rng = pd.date_range('2019-01-01', periods=365, freq='D')
df = pd.DataFrame({ 'Date': rng})
df['flag_workable'] = df['Date'].apply(lambda x: cal.is_working_day(x))
df_workable = df[df['flag_workable'] == True]
df_workable['month'] = df_workable['Date'].dt.month
df_workable['workable_day'] = df_workable.groupby('month')['flag_workable'].cumsum()
print(df)
print(df_workable.head(30))

Выходные данные за январь:

         Date  flag_workable  month  workable_day
1  2019-01-02           True      1           1.0
2  2019-01-03           True      1           2.0
3  2019-01-04           True      1           3.0
6  2019-01-07           True      1           4.0
7  2019-01-08           True      1           5.0

Пример для последних дней января:

         Date  flag_workable  month  workable_day
24 2019-01-25           True      1          18.0
27 2019-01-28           True      1          19.0
28 2019-01-29           True      1          20.0
29 2019-01-30           True      1          21.0
30 2019-01-31           True      1          22.0

Это будет ожидаемый результат после применения обратного кумулятивного значения:

         Date  flag_workable  month  workable_day  inv_workable_day
1  2019-01-02           True      1           1.0              22.0
2  2019-01-03           True      1           2.0              21.0
3  2019-01-04           True      1           3.0              20.0
6  2019-01-07           True      1           4.0              19.0
7  2019-01-08           True      1           5.0              18.0

Последние дни января:

         Date  flag_workable  month  workable_day  inv_workable_day
24 2019-01-25           True      1          18.0               5.0
27 2019-01-28           True      1          19.0               4.0
28 2019-01-29           True      1          20.0               3.0
29 2019-01-30           True      1          21.0               2.0
30 2019-01-31           True      1          22.0               1.0

Ответы [ 2 ]

2 голосов
/ 07 октября 2019

Инвертировать порядок строк в DataFrame до до группировки, так что cumsum рассчитывается в обратном порядке в течение каждого месяца.

df['inv_workable_day'] = df[::-1].groupby('month')['flag_workable'].cumsum()
df['workable_day'] = df.groupby('month')['flag_workable'].cumsum()

#         Date  flag_workable  month  inv_workable_day  workable_day
#1  2019-01-02           True      1               5.0           1.0
#2  2019-01-03           True      1               4.0           2.0
#3  2019-01-04           True      1               3.0           3.0
#6  2019-01-07           True      1               2.0           4.0
#7  2019-01-08           True      1               1.0           5.0
#8  2019-02-01           True      2               1.0           1.0
2 голосов
/ 07 октября 2019

Решение

К какому столбцу вы хотите применить cumsum, у вас есть два варианта:
1. Порядок убывания копии этого столбца по индексу, затем cumsum, а затем порядок возрастания по индексу. Наконец, присвойте его обратно столбцу фрейма данных.

Используйте numpy:
import numpy as np

array = df.column_data.to_numpy()    
array = np.flip(array)  # to flip the order 
array = numpy.cumsum(array)    
array =  numpy.flip(array)  # to flip back to original order    
df.column_data_cumsum = array   
...