Общее число календарных дней на группу Python Pandas - PullRequest
0 голосов
/ 09 января 2019

Я хотел бы рассчитать итоговую совокупную сумму: за все календарные дни"Станция" работает. Мой набор данных не содержит дней, когда станция не работала. Но мне нужно рассчитать скользящее общее количество календарных дней, в течение которых каждая станция работала, по дате начала.

Ниже приведен код, который создает фрейм данных, содержащий разные станции и дни их работы. Я рассчитываю скользящие кумулятивные рабочие дни, теперь мне нужно найти скользящий кумулятивный из календарных дней с даты начала

import pandas as pd
import numpy as np

d = {'Date': ['2011-01-02','2011-01-04','2011-01-05',
              '2011-01-10','2011-01-14','2011-01-15',
              '2011-01-17','2011-01-19','2011-01-22'], 
     'Value': [2,4,66,22,1,2,4,7,9], 
     'Station_ID': ['A','A','A','A','B','B','B','B','B']}
df = pd.DataFrame(data=d)
df['Date'] = df['Date'].values.astype('datetime64[D]')

df

# this gives each stations rolling cumulative number of operating days
df['Rolling_Operating_Days'] = df.groupby('Station_ID')['Date'].rank(method='dense',ascending=True)
df 

Я бы хотел, чтобы результат выглядел так:

Как вы можете видеть, "скользящие календарные дни" начинаются в 1-й календарный день "идентификатора станции", затем кумулятивная скользящая общая сумма суммируется.

Итак, если посмотреть на набор данных ниже, хотя станция работала только 4 или 5 дней ("Rolling_Operating_Days"), общее количество ("Rolling_Calendar_Days") календарных дней составило 9.

    Date    Value   Station_ID  Rolling_Operating_Days  Rolling_Calendar_Days
0   2011-01-02  2   A           1.0                             1.0
1   2011-01-04  4   A           2.0                             3.0
2   2011-01-05  66  A           3.0                             4.0
3   2011-01-10  22  A           4.0                             9.0
4   2011-01-14  1   B           1.0                             1.0
5   2011-01-15  2   B           2.0                             2.0
6   2011-01-17  4   B           3.0                             4.0
7   2011-01-19  7   B           4.0                             6.0
8   2011-01-22  9   B           5.0                             9.0

Я бы хотел вычислить столбец "Rolling_Calendar_Days" . У кого-нибудь есть идеи, как это сделать?

1 Ответ

0 голосов
/ 09 января 2019

Мне кажется, я понимаю, чего вы пытаетесь достичь. Проблема с вашим примером заключается в том, что если день начала не 1 (2011-01-02). Затем он будет начинаться с 2, а не с 1. Решение будет использовать pd.series.diff(), а затем cumsum

давайте предположим, что df_subset:

    Date        Value   Station_ID  
1   2011-01-02  0.961571    A       
3   2011-01-04  -0.927761   A       
4   2011-01-05  0.340300    A       
9   2011-01-10  -1.805910   A       
13  2011-01-14  0.062959    B       
14  2011-01-15  -0.402931   B       
16  2011-01-17  0.696784    B       
18  2011-01-19  -0.039989   B       
21  2011-01-22  -0.547465   B       

тогда вы можете:

# create a func for groupby
def myFunc(x):
    return x['Date'].diff().dt.days.replace(np.nan,1).cumsum()

# apply function to group and reset index
df_subset['Rolling_Calendar_Days'] = df_subset.groupby('Station_ID').apply(myFunc).reset_index(level=0, drop=True)



    Date         Value  Station_ID  Rolling_Calendar_Days
1   2011-01-02  0.961571    A        1.0
3   2011-01-04  -0.927761   A        3.0
4   2011-01-05  0.340300    A        4.0
9   2011-01-10  -1.805910   A        9.0
13  2011-01-14  0.062959    B        1.0
14  2011-01-15  -0.402931   B        2.0
16  2011-01-17  0.696784    B        4.0
18  2011-01-19  -0.039989   B        6.0
21  2011-01-22  -0.547465   B        9.0

это предполагает, что вы хотите, чтобы начальная дата начиналась с 1, а не с 0

...