2016-09-16 98 views
1

我有一个数据框如下,列B的dtype是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 then then'df.groupby([df ['B']。dt.year,df ['B']。dt.day])['A']。size ()'应该工作 – EdChum

+0

@EdChum首先,IINM,你的意思是'df.groupby([df.B.dt.year,df.A])。size()。unstack()';第二,它不起作用 - 它需要年份和月份的组合。 –

+0

@AmiTavory @OmTavory @OPT提到他们希望'或者一般年复一日',所以我回答了这个问题,我没有测试我的代码片段,所以这是一个平底船 – 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

@Sirirbattie谢谢!此外,你的方式看起来更有希望。不幸的是,它的复制粘贴给了我'只对DatetimeIndex,TimedeltaIndex或PeriodIndex有效,但得到'RangeIndex''的实例。如果你能把它作为一个完整的例子,我认为你应该把它作为一个答案本身,因为它看起来更简单。 –

+0

会做,但它基本上是一样的。但为了清晰起见,将添加它。 – Skirrebattie

4

如果将索引设置为日期时间,则可以使用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 

或者可选地(学分艾汉)跳过设置索引步骤,并使用以下单行创建数据帧之后直:

# 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