Python 按月分组
假设我有一个Python 按月分组,python,datetime,pandas,Python,Datetime,Pandas,假设我有一个pd.DataFrame,其中索引由pd.DateTimeIndex给出 现在我想每月分组一对,即获得所有的一对。也就是说,我希望有一个组(日期在(一月,二月)),然后(日期在(二月,三月)),等等。自然的方法应该是pd.TimeGrouper,但我找不到一种方法来实现这一点 下面是一个示例数据集请注意,每月观察一次以上(数字随时间变化),因此pd.rolling()和pd.rolling\u apply()似乎不是有效的替代方案: year month
pd.DataFrame
,其中索引由pd.DateTimeIndex
给出
现在我想每月分组一对,即获得所有的一对。也就是说,我希望有一个组(日期在(一月,二月)
),然后(日期在(二月,三月)
),等等。自然的方法应该是pd.TimeGrouper
,但我找不到一种方法来实现这一点
下面是一个示例数据集请注意,每月观察一次以上(数字随时间变化),因此pd.rolling()
和pd.rolling\u apply()
似乎不是有效的替代方案:
year month cpsidp
date
2000-01-01 2000 1 19981003169301
2000-02-01 2000 2 20000200000101
2000-02-01 2000 2 20000200000102
2000-02-01 2000 2 20000200000103
2000-02-01 2000 2 20000200000104
2000-02-01 2000 2 20000200000105
2000-03-01 2000 3 19981203124802
2000-04-01 2000 4 20000400000101
2000-05-01 2000 5 19990200854301
2000-06-01 2000 6 19990300018604
2000-07-01 2000 7 20000400000101
2000-08-01 2000 8 19990502683801
2000-09-01 2000 9 19990600006901
2000-10-01 2000 10 19990700006501
2000-11-01 2000 11 19990800083001
2000-12-01 2000 12 19991100000301
2001-01-01 2001 1 19991100000301
2001-02-01 2001 2 19991100002701
2001-03-01 2001 3 20000205949101
2001-04-01 2001 4 20010100107701
2001-05-01 2001 5 20000204516501
2001-06-01 2001 6 20000300112801
2001-07-01 2001 7 20000400000101
2001-08-01 2001 8 20000505217801
以下是我将如何以一种非常不寻常的方式创建这些组:
dates = df.index.unique()
for i, date in enumerate(dates):
if i == len(dates) - 1:
# last group: no next-group, break
break
date1, date2 = date, dates[i+1]
group = pd.concat((df.loc[date1], df.loc[date2]), axis=0)
print(group)
试试这个:
In [171]: (df.assign(m1=df.index.year*10**2+df.index.month, m2=df.index.year*10**2+df.index.month+1)
...: .groupby(['m1', 'm2'])
...: .agg({'month':['min','max','size']})
...: )
...:
Out[171]:
month
min max size
m1 m2
200001 200002 1 1 1
200002 200003 2 2 5
200003 200004 3 3 1
200004 200005 4 4 1
200005 200006 5 5 1
200006 200007 6 6 1
200007 200008 7 7 1
200008 200009 8 8 1
200009 200010 9 9 1
200010 200011 10 10 1
200011 200012 11 11 1
200012 200013 12 12 1
200101 200102 1 1 1
200102 200103 2 2 1
200103 200104 3 3 1
200104 200105 4 4 1
200105 200106 5 5 1
200106 200107 6 6 1
200107 200108 7 7 1
200108 200109 8 8 1
不幸的是,
滚动('2M')
不起作用。无论如何,您不能使用rolling(2)
的主要原因是您每月有一次以上的观察。根据每个月对的汇总方式,您可以先每月汇总一次(每月给自己一次观察),然后使用rolling(2)
这非常适用于诸如
'max'
,'min'
,'sum'
,'count'
,'size'
,'first'
,'last'
“平均值”
,“标准值”
。。。等会特别小心。比如,你必须自己使用'sum'
和'count'
并计算'mean'
和std'
,但这是可以做到的。所以像df.groupby(pd.TimeGrouper(frequer='2M')).mean()
不是你需要的吗?@MaxU不,因为这给了我(一月、二月)
和(三月、四月)
-与(1月,2月)
,(2月,3月)
,(3月,4月)
相反,您能发布一个小样本数据集,特别是所需的数据集吗?对不起,我应该更清楚一些。每个月可能有多个观察。如果每个月有多个观察,则此方法不起作用。@FooBar,我已更新了我的答案-这就是您需要的吗?我不确定-在缺少的几个月里它将如何工作…我可以将此与滚动应用程序叠加吗?@FooBar yes。如果你提供更多的细节,我们可以直接回答你的问题。现在,我们在跳舞,试着猜你在找什么。您希望最终输出是什么样子的?如果你有答案,编辑你的问题以反映它。这是一个有趣的想法!我想为每个组做一些复杂的事情,因此我在问题中提出一个方法来对数据进行分组,s.t。然后我可以对分组应用我想要的任何函数,然后@MaxU的答案更合适。
df.groupby(pd.TimeGrouper('M')).first().rolling(2).mean()