Python 如何按时间序列数据分组

Python 如何按时间序列数据分组,python,pandas,Python,Pandas,我在下面有一个数据框,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 我想根据蒙索群比一般的年份和日期 所以我想得到下面的计数结果,key=B列 a b 2016-09 1 2 2016-10 2 0

我在下面有一个数据框,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
我想根据蒙索群比一般的年份和日期

所以我想得到下面的计数结果,key=B列

              a       b
2016-09       1       2
2016-10       2       0
我试过群比。但我不知道如何处理datetime64之类的数据类型。。。 如何处理和分组数据类型datetime64?

假设您从

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)
然后可以按大小分组,然后取消堆叠:

最后,您只需再次确定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
请注意,最终转换为日期-时间设置为统一的日期,您不能有这种类型的无日对象。

假设您从

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)
然后可以按大小分组,然后取消堆叠:

最后,您只需再次确定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

请注意,到日期时间的最终转换将设置为统一的日期,您不能有这种类型的无日对象。

如果将索引设置为日期时间,则可以使用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跳过设置索引步骤,并在创建数据帧后直接使用以下一行:

# 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)

它返回相同的答案

如果将索引设置为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跳过设置索引步骤,并在创建数据帧后直接使用以下一行:

# 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)

它返回相同的答案

IIUC,然后df.groupby[df['B'].dt.year,df['B'].dt.day]['A']work@EdChum首先,IINM,您是指df.groupby[df.B.dt.year,df.A].size.unstack;第二,它不起作用-它需要年和月的组合。@AmiTavory OP提到他们想要的,或者通常是年和天,所以我回答了这个问题,我没有测试我的代码片段,所以它是一个punt@EdChum请不要误会我的意思——你是最细心的回答者之一,一句评论实际上只是一句评论。我只是想指出这一点。祝你一切顺利。@AmiTavory我对被纠正一点也不生气,我只是在解释为什么我要为问题的一部分提供一个可能的解决方案,+1作为你的答案,然后df.groupby[df['B'].dt.year,df['B'].dt.day]['a']。大小应该是work@EdChum首先,IINM,您是指df.groupby[df.B.dt.year,df.A].size.unstack;第二,它不起作用-它需要年和月的组合。@AmiTavory OP提到他们想要的,或者通常是年和天,所以我回答了这个问题,我没有测试我的代码片段,所以它是一个punt@EdChum请不要误会我的意思——你是最细心的回答者之一,一句评论实际上只是一句评论。我只是想指出这一点。祝您一切顺利。@AmiTavory我对被纠正一点也不生气,我只是解释一下为什么我要为问题的一部分提供一个可能的解决方案,+1作为您的答案完美的答案,但是您可以简单地执行df.groupby[pd.TimeGrouper'm','a'].size.unstack,而不是执行困难的日期分组转换。fillna0@Skirrebattie谢谢而且,你的方式看起来更有希望。不幸的是,它的一个拷贝粘贴给了我一个只有DatetimeIndex、TimedeltaIndex或PeriodIndex有效的结果,但是得到了一个“RangeIndex”的实例。如果你能让它在一个完整的例子上工作,我认为你应该把它本身作为一个答案发布,因为它看起来确实更简单。但为了清楚起见,我们会添加它。完美的答案,但不需要进行困难的日期分组转换,您只需执行以下操作:df.groupby[pd.TimeGrouper'M','A'].size.unstack。fillna0@Skirrebattie谢谢而且,你的方式看起来更有希望。不幸的是,它的一个拷贝粘贴给了我一个只有DatetimeIndex、TimedeltaIndex或PeriodIndex有效的结果,但是得到了一个“RangeIndex”的实例。如果你能让它在一个完整的例子上工作,我认为你应该把它本身作为一个答案发布,因为它看起来确实更简单。但为了清楚起见,我们会添加它。TimeGrouper的使用很好。您还可以执行df.groupby[pd.Grouperkey='B',freq='M',A'].size.unstack.fillna0,它不需要将B列设置为索引。TimeGrouper的使用很好。您还可以执行df.groupby[pd.Grouperkey='B',freq='M',A'].size.unstack.fillna0,它不需要将B列设置为索引。