2016-09-16 3 views
1

У меня есть dataframe ниже, dtype столбца B - datetime64.Как группировать данные временных рядов

A  B 
0 a 2016-09-13 
1 b 2016-09-14 
2 b 2016-09-15 
3 a 2016-10-13 
4 a 2016-10-14 

Я хотел бы GroupBy согласно месяца (или вообще год и день ...)

, так что я хотел бы получить результат подсчета ниже, ключ = столбец B.

Я попробовал groupby. но я не мог понять, как обращаться с dtypes как datetime64 ... Как я могу обрабатывать и группировать dtype datetime64?

+0

IIUC затем 'df.groupby ([DF [ 'в']. dt.year, DF [ 'в']. dt.day]) [ 'А']. размер() 'должен работать – EdChum

+0

@EdChum Во-первых, IINM, вы имели в виду' df.groupby ([df.B.dt.year, df.A]). size(). unstack() '; во-вторых, он не работает - ему нужна комбинация года и месяца. –

+0

@AmiTavory OP упомянул, что они хотели «или в целом год и день», поэтому я отвечал на этот запрос, я не тестировал свой фрагмент кода, так что это был punt – EdChum

ответ

3

Допустим, вы начинаете с

In [247]: df = pd.DataFrame({'A': ['a', 'b', 'b', 'a', 'a'], 'B': ['2016-09-13', '2016-09-14', '2016-09-15', '2016-10-13', '2016-10-14']}) 

In [248]: df.B = pd.to_datetime(df.B) 

Тогда вы можете groupby - size, то unstack:

In [249]: df = df.groupby([df.B.dt.year.astype(str) + '-' + df.B.dt.month.astype(str), df.A]).size().unstack().fillna(0).astype(int) 

Наконец, вам просто нужно сделать B дату снова:

In [250]: df.index = pd.to_datetime(df.index) 

In [251]: df 
Out[251]: 
A   a b 
B    
2016-10-01 2 0 
2016-09-01 1 2 

Обратите внимание, что окончательное преобразование в da te-time устанавливает единый день (у вас не может быть «без дневного» объекта этого типа).

+0

Отличный ответ, но вместо того, чтобы выполнять сложную дату с преобразованием, вы можете просто сделать это: df.groupby ([pd.TimeGrouper ('M'), 'A']). Size(). Unstack(). Fillna (0) – Skirrebattie

+1

@Skirrebattie Спасибо! Кроме того, ваш путь выглядит более многообещающим. К сожалению, его копия дала мне «Только действительный с DatetimeIndex, TimedeltaIndex или PeriodIndex, но получил экземпляр« RangeIndex ». Если вы можете заставить его работать над полным примером, я думаю, вы должны опубликовать его как ответ сам по себе, потому что он выглядит проще. –

+0

сделаю, но это в основном то же самое. Но для большей ясности это добавит. – Skirrebattie

4

Если вы указали индекс в datetime, вы можете использовать pd.TimeGrouper для сортировки по различным временным диапазонам. Пример кода:

# recreate dataframe 
df = pd.DataFrame({'A': ['a', 'b', 'b', 'a', 'a'], 'B': ['2016-09-13', '2016-09-14', '2016-09-15', 
                 '2016-10-13', '2016-10-14']}) 
df['B'] = pd.to_datetime(df['B']) 

# set column B as index for use of TimeGrouper 
df.set_index('B', inplace=True) 

# Now do the magic of Ami Tavory's answer combined with timeGrouper: 
df = df.groupby([pd.TimeGrouper('M'), 'A']).size().unstack().fillna(0) 

Это возвращает:

A    a b 
B     
2016-09-30 1.0 2.0 
2016-10-31 2.0 0.0 

или альтернативно (кредиты AYHAN) Пропустить настройку на шаге индекса и использовать следующий один вкладыш сразу после создания dataframe:

# recreate dataframe 
df = pd.DataFrame({'A': ['a', 'b', 'b', 'a', 'a'], 'B': ['2016-09-13', '2016-09-14', '2016-09-15', 
                 '2016-10-13', '2016-10-14']}) 
df['B'] = pd.to_datetime(df['B']) 
df = df.groupby([pd.Grouper(key='B', freq='M'), 'A']).size().unstack().fillna(0) 

который возвращает тот же ответ

+0

Хорошее использование 'TimeGrouper'. –

+0

Вы также можете сделать 'df.groupby ([pd.Grouper (key = 'B', freq = 'M'), 'A']). Size(). Unstack().fillna (0) 'Это не требует установки столбца B в качестве индекса. – ayhan

+0

@ ayhan Это потрясающе, редактируя мой ответ – Skirrebattie

Смежные вопросы