Группа Pandas с несколькими условиями и вычислением разницы дат

#pandas #datetime #pandas-groupby #pivot-table #hierarchical-clustering

#pandas #дата и время #pandas-groupby #сводная таблица #иерархический-кластеризация

Вопрос:

Я застрял в понимании используемого метода. У меня есть следующий фрейм данных:

 df = {'CODE': ['BBLGLC70M','BBLGLC70M','ZZTNRD77', 'ZZTNRD77', 'AACCBD', 'AACCBD', 'BCCDN', 'BCCDN', 'BCCDN'],
      'DATE': ['16/05/2019','25/09/2019', '16/03/2020', '27/02/2020', '16/07/2020', '21/07/2020', '13/02/2020', '23/07/2020', '27/02/2020'],
      'TYPE': ['PRI', 'PRI', 'PRI', 'PRI', 'PUB', 'PUB', 'PUB', 'PRI', 'PUB'],
      'DESC' : ['KO', 'OK', 'KO', 'KO', 'KO', 'OK', 'KO', 'OK', 'OK']
       }

df = pd.DataFrame(df)
df['DATE'] = pd.to_datetime(df['DATE'], format = '%d/%m/%Y')
df
  

введите описание изображения здесь

Мне нужно:

  1. группа с тем же «КОДОМ»,
  2. проверьте, не совпадает ли значение ‘DESC’
  3. проверьте, совпадает ли «ТИП»
  4. вычислите разницу в месяцах между датами, которые удовлетворяют предыдущим 2 командам

Ожидаемый результат выглядит следующим образом:

введите описание изображения здесь

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

1. привет, что ты уже пробовал сам?

2. Здравствуйте, я попытался создать сводную таблицу с кодом, типом и датой в качестве индекса и desc в качестве значений, равных size() . Тогда у меня есть df.groupby(level= 0)[‘DATE’].transform(лямбда x: x[0] — x[1]) вот если бы я ошибся…

Ответ №1:

Следующий код использует .drop_duplicates() и .duplicated() для сохранения или удаления строк из вашего фрейма данных, которые имеют повторяющиеся значения.

Как бы вы рассчитали разницу за месяц? Месяц может составлять 28, 30 или 31 день. Вы можете разделить конечный результат на 30 и получить указание на количество месяцев разницы. Поэтому я пока сохранил его в днях.

 import pandas as pd

df = {'CODE': ['BBLGLC70M','BBLGLC70M','ZZTNRD77', 'ZZTNRD77', 'AACCBD', 'AACCBD', 'BCCDN', 'BCCDN', 'BCCDN'],
      'DATE': ['16/05/2019','25/09/2019', '16/03/2020', '27/02/2020', '16/07/2020', '21/07/2020', '13/02/2020', '23/07/2020', '27/02/2020'],
      'TYPE': ['PRI', 'PRI', 'PRI', 'PRI', 'PUB', 'PUB', 'PUB', 'PRI', 'PUB'],
      'DESC' : ['KO', 'OK', 'KO', 'KO', 'KO', 'OK', 'KO', 'OK', 'OK']
       }

df = pd.DataFrame(df)
df['DATE'] = pd.to_datetime(df['DATE'], format = '%d/%m/%Y')

# only keep rows that have the same code and type 
df = df[df.duplicated(subset=['CODE', 'TYPE'], keep=False)]

# throw out rows that have the same code and desc
df = df.drop_duplicates(subset=['CODE', 'DESC'], keep=False)

# find previous date
df = df.sort_values(by=['CODE', 'DATE'])
df['previous_date'] = df.groupby('CODE')['DATE'].transform('shift')

# drop rows that don't have a previous date
df = df.dropna()

# calculate the difference between current date and previous date
df['difference_in_dates'] = (df['DATE'] - df['previous_date'])
  

Это приводит к следующему df:

 CODE        DATE        TYPE    DESC    previous_date   difference_in_dates
AACCBD      2020-07-21  PUB     OK      2020-07-16      5 days
BBLGLC70M   2019-09-25  PRI     OK      2019-05-16      132 days
BCCDN       2020-02-27  PUB     OK      2020-02-13      14 days