Сгруппировать и получить значение смещения на один год в пандах - PullRequest
1 голос
/ 14 октября 2019

Моя цель сегодня - следить за каждым идентификатором, который принадлежит Category==1 на определенную дату, год спустя. Поэтому у меня есть такой фрейм данных:

Period      ID    Amount   Category
20130101    1       100       1
20130101    2       150       1
20130101    3       100       1
20130201    1       90        1
20130201    2       140       1
20130201    3       95        1
20130201    5       250       0
   .        .       .
20140101    1       40        1
20140101    2       70        1
20140101    5       160       0
20140201    1       35        1
20140201    2       65        1
20140201    5       150       0

Например, в 20130201 у меня есть 2 идентификатора, которые принадлежат Category 1: 1,2,3, но только 2 из них присутствуют в20140201: 1,2. Поэтому мне нужно получить значение Amount, только для этих идентификаторов, через год, например:

Period      ID    Amount   Category    Amount_t1
20130101    1       100       1           40
20130101    2       150       1           70
20130101    3       100       1           nan
20130201    1       90        1           35
20130201    2       140       1           65
20130201    3       95        1           nan
20130201    5       250       0           nan
   .        .       .
20140101    1       40        1           nan
20140101    2       70        1           nan
20140101    5       160       0           nan
20140201    1       35        1           nan 
20140201    2       65        1           nan
20140201    5       150       0           nan  

Итак, если идентификатор не появится в следующем году или будет принадлежать Category0, я получу nan. Мой первый подход состоял в том, чтобы получить список уникальных идентификаторов для каждого Period, а затем попытаться сопоставить его со следующим годом, используя некую комбинацию groupby() и isin(), например:

aux = df[df.Category==1].groupby('Period').ID.unique()
aux.index = aux.index + pd.DateOffset(years=1)

Но я не знал, как продолжать идти. Я думаю, что какой-то groupby('ID') может быть более эффективным. Если бы это был простой shift(), это было бы легко, но я не уверен, как получить смещение значения на год по группе.

1 Ответ

1 голос
/ 14 октября 2019

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

import pandas as pd

# Datetime so we can do calendar year subtraction
df['Period'] = pd.to_datetime(df.Period, format='%Y%m%d')

# Create one with the lagged features. Here I'll split the steps out.
df2 = df.copy()
df2['Period'] = df2.Period-pd.offsets.DateOffset(years=1)  # 1 year lag
df2 = df2.rename(columns={'Amount': 'Amount_t1'})

# Keep only values you want to merge
df2 = df2[df2.Category.eq(1)]

# Bring lagged features
df.merge(df2, on=['Period', 'ID', 'Category'], how='left')

       Period  ID  Amount  Category  Amount_t1
0  2013-01-01   1     100         1       40.0
1  2013-01-01   2     150         1       70.0
2  2013-01-01   3     100         1        NaN
3  2013-02-01   1      90         1       35.0
4  2013-02-01   2     140         1       65.0
5  2013-02-01   3      95         1        NaN
6  2013-02-01   5     250         0        NaN
7  2014-01-01   1      40         1        NaN
8  2014-01-01   2      70         1        NaN
9  2014-01-01   5     160         0        NaN
10 2014-02-01   1      35         1        NaN
11 2014-02-01   2      65         1        NaN
12 2014-02-01   5     150         0        NaN
...