Подсчитать количество случаев за каждый год в панде в зависимости от подгруппы - PullRequest
0 голосов
/ 10 сентября 2018

Представьте себе pandas фрейм данных, заданный

df = pd.DataFrame({
    'id': [1, 1, 1, 2, 2],
    'location': [1, 2, 3, 1, 2],
    'date': [pd.to_datetime('01-01-{}'.format(year)) for year in [2015, 2016, 2015, 2017, 2018]]
}).set_index('id')

, который выглядит так

    location       date
id                     
1          1 2015-01-01
1          2 2016-01-01
1          3 2015-01-01
2          1 2017-01-01
2          2 2018-01-01

Теперь я хочу создать столбец для каждого года, представленного в столбце date, который считает вхождения на id. Следовательно, результирующий фрейм данных должен быть таким:

    location       date  2015  2016  2017  2018
id                                             
1          1 2015-01-01     2     1     0     0
1          2 2016-01-01     2     1     0     0
1          3 2015-01-01     2     1     0     0
2          1 2017-01-01     0     0     1     1
2          2 2018-01-01     0     0     1     1

Теперь я представляю себе использование pd.groupby.transform, но я не могу найти лучшее решение.


Мое собственное решение было

df['year'] = df['date'].map(lambda x: x.year)
df = pd.merge(
    df, 
    pd.pivot_table(df, 'date', 'id', 'year', 'count').fillna(0).astype(int), 
    left_index=True, right_index=True).drop('year', axis=1)

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

get_dummies

df.join(pd.get_dummies(df.date.dt.year).sum(level=0))

         date  location  2015  2016  2017  2018
id                                             
1  2015-01-01         1     2     1     0     0
1  2016-01-01         2     2     1     0     0
1  2015-01-01         3     2     1     0     0
2  2017-01-01         1     0     0     1     1
2  2018-01-01         2     0     0     1     1

factorize

i, r = pd.factorize(df.index)
j, c = pd.factorize(df.date.dt.year)
n, m = shape = len(r), len(c)
b = np.zeros(shape, dtype=np.int64)
np.add.at(b, (i, j), 1)

df.join(pd.DataFrame(b, r, c).rename_axis('id'))

         date  location  2015  2016  2017  2018
id                                             
1  2015-01-01         1     2     1     0     0
1  2016-01-01         2     2     1     0     0
1  2015-01-01         3     2     1     0     0
2  2017-01-01         1     0     0     1     1
2  2018-01-01         2     0     0     1     1
0 голосов
/ 10 сентября 2018

Создать помощника DataFrame с помощью groupby с size, unstack и year и join до оригинала df:

df1 = df.join(df.groupby(['id', df['date'].dt.year]).size().unstack(fill_value=0), on='id')
print (df1)
    location       date  2015  2016  2017  2018
id                                             
1          1 2015-01-01     2     1     0     0
1          2 2016-01-01     2     1     0     0
1          3 2015-01-01     2     1     0     0
2          1 2017-01-01     0     0     1     1
2          2 2018-01-01     0     0     1     1

Деталь:

print (df.groupby(['id', df['date'].dt.year]).size().unstack(fill_value=0))

date  2015  2016  2017  2018
id                          
1        2     1     0     0
2        0     0     1     1

Другое решение с crosstab:

df1 = df.join(pd.crosstab(df.index, df['date'].dt.year), on='id')

print (pd.crosstab(df.index, df['date'].dt.year))
date   2015  2016  2017  2018
row_0                        
1         2     1     0     0
2         0     0     1     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...