【问题标题】:pandas groupby by customized year, e.g. a school yearpandas groupby 按自定义年份,例如一个学年
【发布时间】:2020-03-05 12:46:49
【问题描述】:

在熊猫数据框中,我想找到按“自定义”年份分组的列的平均值。

一个例子是计算一个学年的学校分数的平均值(例如 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

非常感谢!

【问题讨论】:

  • 哇,非常感谢大家!惊讶于您解决此问题的速度!我会将 Quang Hoang 的答案标记为已接受的答案,因为它包含“Q-AUG”财政年度信息——我在文档中找到了这些信息,但无法运行。谢谢大家!

标签: python pandas grouping offset


【解决方案1】:

我们可以手动计算学年:

# 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

【讨论】:

    【解决方案2】:

    另一种方法

    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
    

    【讨论】:

    • 有趣的是你和我如何得到相同的逻辑但得到不同的输出。 (df.index.month == 9).cumsum() 也可以在没有 np.where 的情况下工作。
    • 是的。我认为我们的输出是不同的,因为np.random.randint 用于生成数据集(没有指定seed)。感谢cumsum 的提示,我不知道。
    猜你喜欢
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    相关资源
    最近更新 更多