Разница между первым и текущим строками по группам - PullRequest
2 голосов
/ 30 апреля 2020

У меня есть такой набор данных:

state,date,events_per_day
AM,2020-03-01,100
AM,2020-03-02,120
AM,2020-03-15,200
BA,2020-03-16,80
BA,2020-03-20,100
BA,2020-03-29,150
RS,2020-04-01,80
RS,2020-04-05,100
RS,2020-04-11,160

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

  • для группы «AM» первая дата 2020-03-01;
  • для группы «БА» первая дата 2020-03-16;
  • для группы "RS" это 2020-04-01.

В итоге я хочу получить следующий результат:

state,date,events_per_day,days_after_first_event
AM,2020-03-01,100,0
AM,2020-03-02,120,1    <--- 2020-03-02 - 2020-03-01
AM,2020-03-15,200,14   <--- 2020-03-14 - 2020-03-01
BA,2020-03-16,80,0     
BA,2020-03-20,100,4    <--- 2020-03-20 - 2020-03-16
BA,2020-03-29,150,13   <--- 2020-03-29 - 2020-03-16
RS,2020-04-01,80,0
RS,2020-04-05,100,4    <--- 2020-04-05 - 2020-04-01
RS,2020-04-11,160,10   <--- 2020-04-11 - 2020-04-01

Я нашел Как рассчитать разницу во времени по группам, используя pandas? , и это почти к тому, что я хочу. Однако diff () возвращает разницу между последовательными строками, и мне нужна разница между текущей и первой строками.

Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Вариант 3: groupby.transform

df['days_since_first'] = df['date'] - df.groupby('state')['date'].transform('first')

выход

  state        date  events_per_day days_since_first
0    AM  2020-03-01             100           0 days
1    AM  2020-03-02             120           1 days
2    AM  2020-03-15             200          14 days
3    BA  2020-03-16              80           0 days
4    BA  2020-03-20             100           4 days
5    BA  2020-03-29             150          13 days
6    RS  2020-04-01              80           0 days
7    RS  2020-04-05             100           4 days
8    RS  2020-04-11             160          10 days
2 голосов
/ 30 апреля 2020

Prepossessing:

# convert to datetime
df['date'] = pd.to_datetime(df['date'])

# extract the first dates by states:
first_dates = df.groupby('state')['date'].first()  #.min() works as well

Опция 1: выравнивание индекса

# set_index before substraction allows index alignment
df['days_since_first'] = (df.set_index('state')['date'] - first_dates).values

Опция 2: map:

df['days_since_first'] = df['date'] - df['state'].map(first_dates)

Выход:

  state       date  events_per_day days_since_first
0    AM 2020-03-01             100           0 days
1    AM 2020-03-02             120           1 days
2    AM 2020-03-15             200          14 days
3    BA 2020-03-16              80           0 days
4    BA 2020-03-20             100           4 days
5    BA 2020-03-29             150          13 days
6    RS 2020-04-01              80           0 days
7    RS 2020-04-05             100           4 days
8    RS 2020-04-11             160          10 days
...