Pandas Dataframe: разница между всеми датами для каждого уникального идентификатора - PullRequest
0 голосов
/ 13 февраля 2019
[In 621]: df = pd.DataFrame({'id':[44,44,44,88,88,90,95],
                   'Status': ['Reject','Submit','Draft','Accept','Submit',
                   'Submit','Draft'],
                              'Datetime': ['2018-11-24 08:56:02',
                              '2018-10-24 18:12:02','2018-10-24 08:12:02', 
                              '2018-10-29 13:17:02','2018-10-24 10:12:02',
                              '2018-12-30 08:43:12', '2019-01-24 06:12:02']
                              }, columns = ['id','Status', 'Datetime'])
df['Datetime'] = pd.to_datetime(df['Datetime'])                              
df

Out[621]: 
   id  Status            Datetime
0  44  Reject 2018-11-24 08:56:02
1  44  Submit 2018-10-24 18:12:02
2  44   Draft 2018-10-24 08:12:02
3  88  Accept 2018-10-29 13:17:02
4  88  Submit 2018-10-24 10:12:02
5  90  Submit 2018-12-30 08:43:12
6  95   Draft 2019-01-24 06:12:02

Я пытаюсь получить еще один столбец, например, df['Time in Status'] - это время, которое id провел в этом статусе.

Я смотрел на df.groupby(), но нашел только ответы (, такие как эта ) для работы между двумя датами (например, первая и последняя) независимо от того, сколько дат между ними.

df['Datetime'] = pd.to_datetime(df['Datetime'])                              
g = df.groupby('id')['Datetime']
print(df.groupby('id')['Datetime'].apply(lambda g: g.iloc[-1] - g.iloc[0])) 

id
44   -32 days +23:16:00
88    -6 days +20:55:00
90      0 days 00:00:00
95      0 days 00:00:00
Name: Datetime, dtype: timedelta64[ns]

Наиболее близким к получению результата является DataFrameGroupBy.diff

df['Time in Status'] = df.groupby('id')['Datetime'].diff()
df
   id  Status            Datetime          Time in Status
0  44  Reject 2018-11-24 08:56:02                NaT
1  44  Submit 2018-10-24 18:12:02 -31 days +09:16:00
2  44   Draft 2018-10-24 08:12:02  -1 days +14:00:00
3  88  Accept 2018-10-29 13:17:02                NaT
4  88  Submit 2018-10-24 10:12:02  -6 days +20:55:00
5  90  Submit 2018-12-30 08:43:12                NaT
6  95   Draft 2019-01-24 06:12:02                NaT

Однако с этим есть две проблемы.Во-первых, как я могу выполнить этот расчет, начиная с самой ранней даты и до конца?Например, в строке 2 вместо -1 days +14:00:00 будет 0 Days 10:00:00?Или это легче решить, изменив порядок данных заранее?

Другая проблема - это NaT.Если нет даты для сравнения, то будет использоваться текущий день (т.е. datetime.now).Я мог бы применить это впоследствии достаточно легко, но мне было интересно, может ли быть лучшее решение для поиска и замены всех значений NaT.

1 Ответ

0 голосов
/ 13 февраля 2019

Именно вы правы, сначала необходима сортировка DataFrame.sort_values с обоими столбцами:

df = df.sort_values(['id', 'Datetime'])
df['Time in Status'] = df.groupby('id')['Datetime'].diff()
print (df)
   id  Status            Datetime   Time in Status
2  44   Draft 2018-10-24 08:12:02              NaT
1  44  Submit 2018-10-24 18:12:02  0 days 10:00:00
0  44  Reject 2018-11-24 08:56:02 30 days 14:44:00
4  88  Submit 2018-10-24 10:12:02              NaT
3  88  Accept 2018-10-29 13:17:02  5 days 03:05:00
5  90  Submit 2018-12-30 08:43:12              NaT
6  95   Draft 2019-01-24 06:12:02              NaT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...