按月分组

时间:2016-11-07 12:39:02

标签: python datetime pandas

我们说pd.DataFrame指数由pd.DateTimeIndex给出。

我想现在每月分组,即得到所有对。也就是说,我希望有一个组(date in (January, February)),然后是(date in (February, March))等。自然方式应该是pd.TimeGrouper,但我无法找到一种使这项工作成功的方法。

这是一个示例数据集。 请注意,每月不止一次观察(数字随时间而变化),因此pd.rolling()pd.rolling_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)

2 个答案:

答案 0 :(得分:3)

试试这个:

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

答案 1 :(得分:3)

很遗憾,rolling('2M')无法正常工作。无论如何,你无法使用rolling(2)的主要原因是你每个月有不止一次观察。根据您希望每月聚合的方式,您可以先每月聚合一次(每月给自己一次观察),然后使用rolling(2)

df.groupby(pd.TimeGrouper('M')).first().rolling(2).mean()

enter image description here

这适用于人类汇总统计数据,例如'max''min''sum''count''size''first',{{1 }}

'last''mean',......等会特别小心。比如,您必须自己使用'std''sum'并自行计算'count''mean',但可以这样做。