Каков эффективный способ вычислить разницу в датах с момента последнего обслуживания?

#python #pandas

#python #pandas

Вопрос:

Ниже приведен пример набора данных, с которым я работаю:

             maint id
datetime            
2015-01-01    1.0  a
2015-01-02    NaN  a
2015-01-03    NaN  a
2015-01-04    1.0  a
2015-01-05    NaN  a
2015-01-06    NaN  a
2015-01-07    NaN  a
2015-01-01    NaN  b
2015-01-02    NaN  b
2015-01-03    1.0  b
2015-01-04    1.0  b
2015-01-05    NaN  b
2015-01-06    NaN  b
2015-01-07    NaN  b
  

Что я хочу получить, так это разницу в днях, поскольку df['maint'] равно 1.

             maint id  days
datetime                  
2015-01-01    1.0  a     0
2015-01-02    NaN  a     1
2015-01-03    NaN  a     2
2015-01-04    1.0  a     0
2015-01-05    NaN  a     1
2015-01-06    NaN  a     2
2015-01-07    NaN  a     3
2015-01-01    NaN  b     0
2015-01-02    NaN  b     0
2015-01-03    1.0  b     0
2015-01-04    1.0  b     0
2015-01-05    NaN  b     1
2015-01-06    NaN  b     2
2015-01-07    NaN  b     3
  

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

Ответ №1:

Используйте:

 df['days'] = df.index.where(df['maint'].eq(1))
df['days'] = (df.index - df.groupby('id')['days'].ffill()).fillna(pd.Timedelta(0)).dt.days
print (df)
            maint id  days
datetime                  
2015-01-01    1.0  a     0
2015-01-02    NaN  a     1
2015-01-03    NaN  a     2
2015-01-04    1.0  a     0
2015-01-05    NaN  a     1
2015-01-06    NaN  a     2
2015-01-07    NaN  a     3
2015-01-01    NaN  b     0
2015-01-02    NaN  b     0
2015-01-03    1.0  b     0
2015-01-04    1.0  b     0
2015-01-05    NaN  b     1
2015-01-06    NaN  b     2
2015-01-07    NaN  b     3
  

Объяснение:

  1. Сначала создайте новый столбец days со значениями, df.index где maint есть 1 , другие значения NaT
  2. Вычтите index из новой серии, созданной GroupBy.ffill , замените NaN s на 0 timedelta и в последний раз преобразуйте их в дни на Series.dt.days