使用pandas Grouper在十年开始时对DataFrame进行分组

mfl*_*abu 6 python group-by pandas pandas-groupby

我有一个从01-01-1973到12-31-2014的每日观察数据框.

一直在使用Pandas Grouper,到目前为止,每个频率都运行良好:我希望将它们分组为70年代,80年代,90年代等.

我试着这样做

import pandas as pd
df.groupby(pd.Grouper(freq = '10Y')).mean()
Run Code Online (Sandbox Code Playgroud)

然而,这将他们分为73-83,83-93等.

ALo*_*llz 11

pd.cut 也适用于指定具有指定开始年份的常规频率.

import pandas as pd
df
                 date  val
0 1970-01-01 00:01:18    1
1 1979-12-31 18:01:01   12
2 1980-01-01 00:00:00    2
3 1989-01-01 00:00:00    3
4 2014-05-06 00:00:00    4

df.groupby(pd.cut(df.date, pd.date_range('1970', '2020', freq='10YS'), right=False)).mean()
#                          val
#date                         
#[1970-01-01, 1980-01-01)  6.5
#[1980-01-01, 1990-01-01)  2.5
#[1990-01-01, 2000-01-01)  NaN
#[2000-01-01, 2010-01-01)  NaN
#[2010-01-01, 2020-01-01)  4.0
Run Code Online (Sandbox Code Playgroud)


cs9*_*s95 7

你可以在一年中做一点算术,将它放到最近的十年:

df.groupby(df.index.year // 10 * 10).mean()
Run Code Online (Sandbox Code Playgroud)


sac*_*cuL 5

@c\xe1\xb4\x8f\xca\x9f\xe1\xb4\x85s\xe1\xb4\x98\xe1\xb4\x87\xe1\xb4\x87\xe1\xb4\x85 的方法比这个更干净,但保持您的pd.Grouper方法,一种方法是将您的数据与从十年开始到十年结束的新日期范围合并,然后使用您的Grouper数据。例如,给定初始df

\n\n
        date      data\n0     1973-01-01 -1.097895\n1     1973-01-02  0.834253\n2     1973-01-03  0.134698\n3     1973-01-04 -1.211177\n4     1973-01-05  0.366136\n...\n15335 2014-12-27 -0.566134\n15336 2014-12-28 -1.100476\n15337 2014-12-29  0.115735\n15338 2014-12-30  1.635638\n15339 2014-12-31  1.930645\n
Run Code Online (Sandbox Code Playgroud)\n\n

将其与date_range1980 年至 2020 年的数据框合并:

\n\n
new_df = pd.DataFrame({'date':pd.date_range(start='01-01-1970', end='12-31-2019', freq='D')})\n\ndf = new_df.merge(df, on ='date', how='left')\n
Run Code Online (Sandbox Code Playgroud)\n\n

并使用你的Grouper

\n\n
df.groupby(pd.Grouper(key='date', freq = '10AS')).mean()\n
Run Code Online (Sandbox Code Playgroud)\n\n

这给你:

\n\n
                data\ndate                \n1970-01-01 -0.005455\n1980-01-01  0.028066\n1990-01-01  0.011122\n2000-01-01  0.011213\n2010-01-01  0.029592\n
Run Code Online (Sandbox Code Playgroud)\n\n

相同,但一口气,可能看起来像这样:

\n\n
(df.merge(pd.DataFrame(\n    {'date':pd.date_range(start='01-01-1970',\n                          end='12-31-2019',\n                          freq='D')}),\n          how='right')\n .groupby(pd.Grouper(key='date', freq = '10AS'))\n .mean())\n
Run Code Online (Sandbox Code Playgroud)\n