【问题标题】:Grouping data by specific years in python在python中按特定年份对数据进行分组
【发布时间】:2018-09-17 03:50:51
【问题描述】:

我想创建一个按地区和日期分组的数据框,以显示特定年份中某个地区的平均年龄。所以我的列看起来像

地区、年份、平均年龄

目前为止:

#specify aggregation functions to column'age'    
ageAverage = {'age':{'average age':'mean'}} 

#groupby and apply functions    
ageDataFrame = data.groupby(['Region', data.Date.dt.year]).agg(ageAverage)

这很好用,但我怎样才能做到只对特定年份的数据进行分组呢?比如在 2010 年到 2015 年之间?

【问题讨论】:

    标签: python pandas aggregate pandas-groupby


    【解决方案1】:

    使用@jezrael 的数据的两个变体(谢谢)
    这些非常接近@jezrael 已经展示的内容。仅将此视为可以做其他事情的演示。正如@jezrael 在 cmets 中指出的那样,最好先进行预过滤,因为它会减少整体处理。

    pandas.IndexSlice

    而不是使用between进行预过滤

    data.groupby(
        ['Region', data.Date.dt.year]
    
    )['average age'].agg(
        [('age', 'mean')]
    
    ).loc[pd.IndexSlice[:, 2010:2015], :]
    
                 age
    Region Date     
    reg1   2010    2
           2011    2
    reg2   2012    6
           2013   17
           2014   19
           2015   10
    

    between 作为groupby 的一部分

    data.groupby(
        [data.Date.dt.year.between(2010, 2015),
         'Region', data.Date.dt.year]
    
    )['average age'].agg(
        [('age', 'mean')]
    
    ).loc[True]
    
                 age
    Region Date     
    reg1   2010    2
           2011    2
    reg2   2012    6
           2013   17
           2014   19
           2015   10
    

    【讨论】:

    • 我认为为了获得更好的性能,最好先删除不必要的数据,然后再删除groupby - 通常更少的数据处理,更好的性能。你怎么看?
    • 我完全同意。我正要进一步编辑。先检查其他问题(-:
    【解决方案2】:

    你需要先过滤between:

    ageDataFrame = (data[data.Date.dt.year.between(2010, 2015)]
                      .groupby(['Region', data.Date.dt.year])
                      .agg(ageAverage))
    

    同样在last version of pandas 0.22.0获取:

    规范错误:无法使用嵌套字典执行年龄重命名

    正确的解决方案是在groupby 之后指定列表中的列并按tuple 聚合 - 第一个值是新列名和第二个聚合函数:

    np.random.seed(123)
    
    rng = pd.date_range('2009-04-03', periods=10, freq='13M')
    data = pd.DataFrame({'Date': rng,
                         'Region':['reg1'] * 3 + ['reg2'] * 7,
                         'average age': np.random.randint(20, size=10)})  
    print (data)
            Date Region  average age
    0 2009-04-30   reg1           13
    1 2010-05-31   reg1            2
    2 2011-06-30   reg1            2
    3 2012-07-31   reg2            6
    4 2013-08-31   reg2           17
    5 2014-09-30   reg2           19
    6 2015-10-31   reg2           10
    7 2016-11-30   reg2            1
    8 2017-12-31   reg2            0
    9 2019-01-31   reg2           17
    
    ageAverage = {('age','mean')}
    
    #groupby and apply functions    
    ageDataFrame = (data[data.Date.dt.year.between(2010, 2015)]
                     .groupby(['Region', data.Date.dt.year])['average age']
                     .agg(ageAverage))
    print (ageDataFrame)
                 age
    Region Date     
    reg1   2010    2
           2011    2
    reg2   2012    6
           2013   17
           2014   19
           2015   10
    

    【讨论】:

    • 哦,太好了!我不知道我可以在两者之间使用。非常感谢,工作完美。
    • 一种相关但随机的问题,我试图弄清楚如何在箱线图中绘制该数据框,但似乎无法正确解决。到目前为止,我使用 seaborn:sns.plot(kind='box', y='age', x='date', hue='age', data=ageDataFrame, size=8, aspect=1.5, legend_out=true) 有什么想法吗?
    • @user3452963 - 我认为首先需要reset_index(),比如ageDataFrame = (data[data.Date.dt.year.between(2010, 2015)] .groupby(['Region', data.Date.dt.year])['average age'] .agg(ageAverage) .reset_index()) print (ageDataFrame),然后是sns.boxplot(y='age', x='Date', hue='age', data=ageDataFrame)docs
    • @user3452963 - 不确定,但似乎问题是需要未聚合的数据。
    • @user3452963 - 例如我测试np.random.seed(123) L = list('abcde') N = 100 rng = pd.date_range('2009-04-03', periods=N, freq='1M') data = pd.DataFrame({'Date': rng, 'Region':np.random.choice(L, size=N), 'average age': np.random.rand(N)}) print (data) data = data[data.Date.dt.year.between(2010, 2015)] data.Date = data.Date.dt.year sns.boxplot(y='average age', x='Date', hue='Region', data=data)
    猜你喜欢
    • 2017-11-04
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 2019-04-17
    相关资源
    最近更新 更多