Python — группировка различий в днях по элементам

#python #pandas #pandas-groupby

#python #pandas #pandas-groupby

Вопрос:

Я ищу эффективный способ сгенерировать разницу в количестве дней с начального момента времени. Начальный момент времени в первый раз (минимальная дата) идентификатор запускается значением Y в столбце индикатора.

Ввод

 ID   Indicator  Date
111  Y          1/20/2020
111  N          1/23/2020
111  Y          1/26/2020
111  N          1/26/2020
123  N          1/1/2020
123  Y          1/23/2020
123  Y          2/5/2020
 

Вывод

 ID   Indicator  Date         Daysdiff
111  Y          1/20/2020    0
111  N          1/23/2020    3
111  Y          1/26/2020    6
111  N          1/26/2020    6
123  N          1/1/2020     -22
123  Y          1/23/2020    0 
123  Y          2/5/2020     12
 
 df['Date'] = pd.to_datetime(df['Date'])
df['Daysdiff'] = df.groupby('ID')['Date'].diff().fillna('')
 

Моя трудность заключается в том, чтобы выяснить, как реализовать начальную точку, где должен быть день 0, когда идентификатор имеет индикатор Y в самой ранней точке.

Ответ №1:

Давайте попробуем с groupby().idxmax :

 idx = df['Indicator'].eq('Y').groupby(df['ID']).transform('idxmax')
df['Daysdiff'] = df['Date'] - df.loc[idx, 'Date'].values
 

Вывод:

     ID Indicator       Date Daysdiff
0  111         Y 2020-01-20   0 days
1  111         N 2020-01-23   3 days
2  111         Y 2020-01-26   6 days
3  111         N 2020-01-26   6 days
4  123         N 2020-01-01 -22 days
5  123         Y 2020-01-23   0 days
6  123         Y 2020-02-05  13 days
 

Обратите внимание, что с тех пор 'Y' > 'N' должно было сработать следующее, но это не работает в моей системе:

 idx = df['Indicator'].groupby(df['ID']).transform('idxmax')
 

Комментарии:

1. Быстрый вопрос, вы случайно не знаете, почему я получаю следующую ошибку «неподдерживаемые типы операндов для -: ‘str’ и ‘str'»? Это происходит, когда я пытаюсь запустить вашу вторую строку кода — спасибо!

2. Ваш столбец даты по-прежнему является строкой. Вы забыли pd.to_datetime , как в вашем вопросе?

3. Спасибо и извините… Я забыл об этом!

Ответ №2:

Вы также можете сортировать, а затем получать first дату с groupby помощью . Затем получите разницу:

 first = (df.sort_values(['ID', 'Indicator', 'Date'], ascending=[True,False,True])
           .groupby('ID')['Date'].transform('first'))
df['Daysdiff'] = (df['Date'] - first).dt.days
df
Out[1]: 
    ID Indicator       Date  Daysdiff
0  111         Y 2020-01-20         0
1  111         N 2020-01-23         3
2  111         Y 2020-01-26         6
3  111         N 2020-01-26         6
4  123         N 2020-01-01       -22
5  123         Y 2020-01-23         0
6  123         Y 2020-02-05        13