【问题标题】:Python Pandas groupby or rolling multi year average summary statisticsPython Pandas groupby 或滚动多年平均汇总统计
【发布时间】:2018-07-14 15:13:01
【问题描述】:

我有一个 pandas 时间序列数据框,从 2014 年到 2017 年,每年大约有 20 行,我正在尝试计算每两年期间的平均值。例如:01/1/2014 ... 31/12/2015、01/1/2015 ... 31/12/2016、01/1/2016 ... 31/12/2017

这是我用来导入 DataFrame 的代码:

import pandas as pd

infile = 'https://environment.data.gov.uk/bwq/downloadAPI/requestDownload?report=samples&bw=ukj2100-14950&to=2018-02-05&from=2014-05-01'
df = pd.read_csv(infile,compression='zip',usecols=['intestinalEnterococciCount','sampleTime'], parse_dates=['sampleTime'],infer_datetime_format=True,index_col=['sampleTime'],na_values=True)

还有一个DataFrame的例子:

                     intestinalEnterococciCount
sampleTime                                     
2014-05-12 13:00:00                          10
2014-05-21 12:27:00                          10
2014-05-27 10:55:00                          10
2014-06-06 12:19:00                          10
2014-06-09 13:26:00                          10

我想计算每两年的平均值。预期的答案是:

Period                Mean
Jan 2014 - Dec 2015:  33.575
Jan 2015 - Dec 2016:  22.85
Jan 2016 - Dec 2017:  25.5

我尝试了什么:

  • 我知道我可以使用循环并遍历两年期间的列表并以这种方式进行计算,但我确信使用 Pandas 必须有更好的方法来实现这一点。
  • 我尝试使用 .rolling,但这似乎给出了滚动平均值,它逐行递增,而不是超过两年。
  • 我可以成功地使用groupby(df.index.year).mean 获得每年的平均值,但是我该如何计算每两年的平均值?

【问题讨论】:

    标签: python pandas summary rolling-computation


    【解决方案1】:

    您可以使用 groupbyrolling ,确保记录计数和总和以供将来计算平均值,(您只需使用 s.index=[your index list] 将索引更改为您需要的值)

    s=df.groupby(df.index.strftime('%Y')).intestinalEnterococciCount.agg(['sum','count'])
    
    s=s.rolling(window=2).sum()
    
    s['mean']=s['sum']/s['count']
    
    s.dropna()
    
    Out[564]: 
             sum  count    mean
    2015  1343.0   40.0  33.575
    2016   914.0   40.0  22.850
    2017   765.0   30.0  25.500
    

    更新:

    s=df.groupby(df.index.strftime('%Y')).intestinalEnterococciCount.apply(list)
    (s+s.shift()).dropna().apply(pd.Series).stack().std(level=0)
    Out[601]: 
    2015    76.472179
    2016    33.701974
    2017    34.845224
    dtype: float64
    

    【讨论】:

    • @JCM yw~ :-) 如果有帮助,你能考虑接受吗? :-)
    • 感谢完美。但是,我不知道如何修改它来计算两年期间的其他统计数据,例如标准差和几何平均值。谢谢。
    • @JCM,要获得标准差(默认情况下分母为N - 1 - 请参阅Bessel's correction),请将'std' 添加到@Wen 答案第一行的列表中。对于几何平均值,运行from scipy.stats.mstats import gmean,然后将gmean(不带引号)添加到同一个列表中。
    • @PeterLeimbigler 可以计算每一年的标准差和几何平均值,但对于两年块来说是不正确的
    • @JCM,你是对的。为了便于阅读,我将为 stdev 和 gmean 编写解决方案。
    【解决方案2】:

    要获得标准差和几何平均值等其他汇总统计数据,这里有一个有点老套的方法:

    df_std = pd.DataFrame([df[str(y):str(y+2)].std() for y in df.index.year.unique()])
    df_std.index = df.index.year.unique().sort_values()
    
    df_std
                intestinalEnterococciCount
    sampleTime
    2014                         63.825528
    2015                         37.596271
    2016                         34.845224
    2017                         51.384066
    
    from scipy.stats.mstats import gmean
    df_gm = pd.DataFrame([df[str(y):str(y+2)].agg(gmean) for y in df.index.year.unique()])
    df_gm.index = df.index.year.unique().sort_values()
    
    df_gm
                intestinalEnterococciCount
    sampleTime
    2014                         16.230186
    2015                         16.136248
    2016                         16.377124
    2017                         19.529690
    

    【讨论】:

    • 这比我使用循环的方法更好,也更好。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多