pandas 按自定义年份分组,例如一个学年
pandas groupby by customized year, e.g. a school year
在 pandas 数据框中,我想找到按 'customized' 年份分组的列的平均值。
一个例子是计算一个学年的学校分数的平均值(例如 Sep/YYYY 到 Aug/YYYY+1)。
pandas 文档提供了一些关于偏移量和营业年度等的信息,但我无法从中真正理解得到一个工作示例。
这是一个最小的例子,其中每年(1 月至 12 月)计算学校分数的平均值,这是我 不想要的 。
import pandas as pd
import numpy as np
df = pd.DataFrame(data=np.random.randint(low=1, high=5, size=36),
index=pd.date_range('2001-09-01', freq='M', periods=36),
columns=['marks'])
df_yearly = df.groupby(pd.Grouper(freq="A")).mean()
这可能产生例如:
print(df):
marks
2001-09-30 1
2001-10-31 4
2001-11-30 2
2001-12-31 1
2002-01-31 4
2002-02-28 1
2002-03-31 2
2002-04-30 1
2002-05-31 3
2002-06-30 3
2002-07-31 3
2002-08-31 3
2002-09-30 4
2002-10-31 1
...
2003-11-30 4
2003-12-31 2
2004-01-31 1
2004-02-29 2
2004-03-31 1
2004-04-30 3
2004-05-31 4
2004-06-30 2
2004-07-31 2
2004-08-31 4
print(df_yearly):
marks
2001-12-31 2.000000
2002-12-31 2.583333
2003-12-31 2.666667
2004-12-31 2.375000
我想要的输出对应于:
2001-09/2002-08 mean_value
2002-09/2003-08 mean_value
2003-09/2004-08 mean_value
非常感谢!
我们可以手动计算学年:
# if month>=9 we move it to the next year
school_years = df.index.year + (df.index.month>8).astype(int)
另一种选择是使用从 9 月开始的会计年度:
school_years = df.index.to_period('Q-AUG').qyear
我们可以分组:
df.groupby(school_years).mean()
输出:
marks
2002 2.333333
2003 2.500000
2004 2.500000
另一种方法
a = (df.index.month == 9).cumsum()
val = df.groupby(a, sort=False)['marks'].mean().reset_index()
dates = df.index.to_series().groupby(a, sort=False).agg(['first', 'last']).reset_index()
dates.merge(val, on='index')
输出
index first last marks
0 1 2001-09-30 2002-08-31 2.750000
1 2 2002-09-30 2003-08-31 2.333333
2 3 2003-09-30 2004-08-31 2.083333
在 pandas 数据框中,我想找到按 'customized' 年份分组的列的平均值。
一个例子是计算一个学年的学校分数的平均值(例如 Sep/YYYY 到 Aug/YYYY+1)。 pandas 文档提供了一些关于偏移量和营业年度等的信息,但我无法从中真正理解得到一个工作示例。
这是一个最小的例子,其中每年(1 月至 12 月)计算学校分数的平均值,这是我 不想要的 。
import pandas as pd
import numpy as np
df = pd.DataFrame(data=np.random.randint(low=1, high=5, size=36),
index=pd.date_range('2001-09-01', freq='M', periods=36),
columns=['marks'])
df_yearly = df.groupby(pd.Grouper(freq="A")).mean()
这可能产生例如:
print(df):
marks
2001-09-30 1
2001-10-31 4
2001-11-30 2
2001-12-31 1
2002-01-31 4
2002-02-28 1
2002-03-31 2
2002-04-30 1
2002-05-31 3
2002-06-30 3
2002-07-31 3
2002-08-31 3
2002-09-30 4
2002-10-31 1
...
2003-11-30 4
2003-12-31 2
2004-01-31 1
2004-02-29 2
2004-03-31 1
2004-04-30 3
2004-05-31 4
2004-06-30 2
2004-07-31 2
2004-08-31 4
print(df_yearly):
marks
2001-12-31 2.000000
2002-12-31 2.583333
2003-12-31 2.666667
2004-12-31 2.375000
我想要的输出对应于:
2001-09/2002-08 mean_value
2002-09/2003-08 mean_value
2003-09/2004-08 mean_value
非常感谢!
我们可以手动计算学年:
# if month>=9 we move it to the next year
school_years = df.index.year + (df.index.month>8).astype(int)
另一种选择是使用从 9 月开始的会计年度:
school_years = df.index.to_period('Q-AUG').qyear
我们可以分组:
df.groupby(school_years).mean()
输出:
marks
2002 2.333333
2003 2.500000
2004 2.500000
另一种方法
a = (df.index.month == 9).cumsum()
val = df.groupby(a, sort=False)['marks'].mean().reset_index()
dates = df.index.to_series().groupby(a, sort=False).agg(['first', 'last']).reset_index()
dates.merge(val, on='index')
输出
index first last marks
0 1 2001-09-30 2002-08-31 2.750000
1 2 2002-09-30 2003-08-31 2.333333
2 3 2003-09-30 2004-08-31 2.083333