В группе переместите дату на ту же дату в предыдущем году, если выполняются определенные условия - PullRequest
3 голосов
/ 13 июля 2020

У меня есть pandas фрейм данных, который выглядит следующим образом

pd.DataFrame({'a':['cust1', 'cust1', 'cust1', 'cust1', 'cust1', 'cust1', 'cust1', 'cust2', 'cust2', 'cust3', 'cust3', 'cust3'],
                   'date':[date(2017, 6, 15), date(2017, 12, 15), date(2018, 6, 15), date(2019, 1, 20), date(2019, 6, 15), date(2020, 1, 10), date(2020, 6, 12), date(2017, 12, 15), date(2018, 12, 10), date(2017, 1, 5), date(2018, 1, 15), date(2019, 2, 20)],
                   'c':[5, 5, 6, 6, 7, 7, 8, 4, 8, 6, 5, 9]})

        a        date  c
0   cust1  2017-06-15  5
1   cust1  2017-12-15  5
2   cust1  2018-06-15  6
3   cust1  2019-01-20  6
4   cust1  2019-06-15  7
5   cust1  2020-01-10  7
6   cust1  2020-06-12  8
7   cust2  2017-12-15  4
8   cust2  2018-12-10  8
9   cust3  2017-01-05  6
10  cust3  2018-01-15  5
11  cust3  2019-02-20  9

a '= customer

' date '= дата, когда клиент заплатил

' c '= сумма, уплаченная клиентом

Мне нужно проверить, платил ли клиент столько раз в год, сколько в предыдущем году, но для клиентов, которые обычно платили в декабре, но в последующие годы платили в январе, я хотел бы измените дату января на дату декабря.

Я пробовал следующее:

year_end_month = [1, 12]
df['date'] = pd.to_datetime(df['date'], errors='coerce')
df_2 = df.loc[df['date'].dt.month.isin(year_end_month)].copy()
df_3 = pd.concat([df, df_2]).drop_duplicates(keep=False)
s=df_2.groupby('a').date.shift().dt.month
df_2['newDate']=np.where(s.eq(12) & df_2.date.dt.month.eq(1), df_2.date- 
pd.DateOffset(months=1), df_2.date)
df_4 = pd.concat([df_2, df_3])
df_4.newDate = df_4.newDate.fillna(df_4.date)
df_4.sort_values(by=['a', 'date'])

Проблема с моим подходом в том, что он работает при первом переносе даты платежа с декабря на январь но это не работает в последующие годы. Итак, глядя на cust1, она впервые переключила платеж с декабря на январь в декабре 2018 года на январь 2019 года, и мой подход отражает это. но мой подход не позволяет переместить ее платеж за 2019 год, который она сделала в январе 2020 года, на декабрь 2019 года. Есть идеи, как это можно решить?

мой итоговый фрейм данных должен выглядеть так:

        a       date  c    newDate
0   cust1 2017-06-15  5 2017-06-15
1   cust1 2017-12-15  5 2017-12-15
2   cust1 2018-06-15  6 2018-06-15
3   cust1 2019-01-20  6 **2018-12-20**
4   cust1 2019-06-15  7 2019-06-15
5   cust1 2020-01-10  7 **2019-12-10**
6   cust1 2020-06-12  8 2020-06-12
7   cust2 2017-12-15  4 2017-12-15
8   cust2 2018-12-10  8 2018-12-10
9   cust3 2017-01-05  6 2017-01-05
10  cust3 2018-01-15  5 2018-01-15
11  cust3 2019-02-20  9 2019-02-20

1 Ответ

2 голосов
/ 13 июля 2020

Давайте попробуем ffill() на серии shift() месяцев

months = df.date.dt.month

s = months.eq(12).groupby(df['a']).shift()
df['date'] = np.where(months.eq(1) & s.where(s).groupby(df['a']).ffill(),
                      df['date'] - pd.tseries.offsets.MonthOffset(),
                      df['date'])

Вывод:

        a       date  c
0   cust1 2017-06-15  5
1   cust1 2017-12-15  5
2   cust1 2018-06-15  6
3   cust1 2018-12-20  6
4   cust1 2019-06-15  7
5   cust1 2019-12-10  7
6   cust1 2020-06-12  8
7   cust2 2017-12-15  4
8   cust2 2018-12-10  8
9   cust3 2017-01-05  6
10  cust3 2018-01-15  5
11  cust3 2019-02-20  9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...