1. ホーム
  2. python

パンダのgroupby月と年

2023-07-18 06:08:28

質問

以下のようなデータフレームがあります。

Date        abc    xyz
01-Jun-13   100    200
03-Jun-13   -20    50
15-Aug-13   40     -5
20-Jan-14   25     15
21-Feb-14   60     80

例えば、2013年1月、2013年2月、2013年3月...といった具合に、年や月でデータをグループ化する必要があります。 新しくグループ化されたデータを使って、年/月ごとのabc対xyzを示すプロットを作成する予定です。

groupby と sum のさまざまな組み合わせを試しましたが、何も動作しないようです。

何かありましたら、よろしくお願いします。

どのように解決するのですか?

リサンプルか Grouper (これはフードの下で再サンプリングします)のどちらかを使用します。

まず、datetimeカラムが実際にdatetimeであることを確認します(それを pd.to_datetime ). DatetimeIndexであれば、より簡単です。

In [11]: df1
Out[11]:
            abc  xyz
Date
2013-06-01  100  200
2013-06-03  -20   50
2013-08-15   40   -5
2014-01-20   25   15
2014-02-21   60   80

In [12]: g = df1.groupby(pd.Grouper(freq="M"))  # DataFrameGroupBy (grouped by Month)

In [13]: g.sum()
Out[13]:
            abc  xyz
Date
2013-06-30   80  250
2013-07-31  NaN  NaN
2013-08-31   40   -5
2013-09-30  NaN  NaN
2013-10-31  NaN  NaN
2013-11-30  NaN  NaN
2013-12-31  NaN  NaN
2014-01-31   25   15
2014-02-28   60   80

In [14]: df1.resample("M", how='sum')  # the same
Out[14]:
            abc  xyz
Date
2013-06-30   40  125
2013-07-31  NaN  NaN
2013-08-31   40   -5
2013-09-30  NaN  NaN
2013-10-31  NaN  NaN
2013-11-30  NaN  NaN
2013-12-31  NaN  NaN
2014-01-31   25   15
2014-02-28   60   80

注意:以前は pd.Grouper(freq="M") という書き方をしていました。 pd.TimeGrouper("M") . 後者は0.21から非推奨になりました。


以下のようにすればうまくいくと思っていたのですが、うまくいきません(原因として as_index が尊重されていない?よくわからないのですが)。興味本位で載せておきます。

カラムであれば(datetime64のカラムでなければならない!と言っているように、それを打つのは to_datetime を打ってください)、PeriodIndexを使うことができます。

In [21]: df
Out[21]:
        Date  abc  xyz
0 2013-06-01  100  200
1 2013-06-03  -20   50
2 2013-08-15   40   -5
3 2014-01-20   25   15
4 2014-02-21   60   80

In [22]: pd.DatetimeIndex(df.Date).to_period("M")  # old way
Out[22]:
<class 'pandas.tseries.period.PeriodIndex'>
[2013-06, ..., 2014-02]
Length: 5, Freq: M

In [23]: per = df.Date.dt.to_period("M")  # new way to get the same

In [24]: g = df.groupby(per)

In [25]: g.sum()  # dang not quite what we want (doesn't fill in the gaps)
Out[25]:
         abc  xyz
2013-06   80  250
2013-08   40   -5
2014-01   25   15
2014-02   60   80

望ましい結果を得るためには、再インデックス化する必要があります...