在python中按特定年份分组数据

在python中按特定年份分组数据,python,pandas,aggregate,pandas-groupby,Python,Pandas,Aggregate,Pandas Groupby,我想创建一个按地区和日期分组的数据框,它显示特定年份内地区的平均年龄。所以我的柱子看起来像 地区、年份、平均年龄 到目前为止,我已经: #specify aggregation functions to column'age' ageAverage = {'age':{'average age':'mean'}} #groupby and apply functions ageDataFrame = data.groupby(['Region', data.Date.dt.y

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

地区、年份、平均年龄

到目前为止,我已经:

#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年之间?

您首先需要通过以下方式进行筛选:

同样在get中:

SpecificationError:无法使用嵌套字典对年龄执行重命名

正确的解决方案是在列表中指定
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

使用@jezrael数据(thx)的两种变体
这些与@jezrael已经展示的非常接近。仅将此视为其他操作的演示。正如@jezrael在评论中指出的,最好先进行预过滤,因为这样会减少整体处理

pandas.indexlice
而不是在

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的一部分

哦,太好了!我不知道我可以在两者之间使用。非常感谢,效果很好。这是一个相关但随机的问题,我试图找出如何在箱线图中绘制数据帧,但似乎无法正确绘制。到目前为止,我在使用seaborn时所做的:
sns.plot(kind='box',y='age',x='date',hue='age',data=ageDataFrame,size=8,aspect=1.5,legend\u out=true)
有什么想法吗?@user3452963-我想首先需要
重置索引()
比如
ageDataFrame=(data[data.date.dt.year.between(2010,2015)]。groupby(['Region',data.Date.dt.year])['average age'].agg(ageAverage).reset_index())打印(ageDataFrame)
然后
sns.boxplot(y='age',x='Date',hue='age',data=ageDataFrame)
,@user3452963-不确定,但问题似乎是需要未聚合的数据。@user3452963-例如,我测试
np.random.seed(123)L=list('abcde')N=100 rng=pd.date\u range('2009-04-03',periods=N,freq=1M')data=pd.DataFrame({'date:rng',Region':np random.choice(L,size=N),“平均年龄”:np.random.rand(N)})打印(数据)数据=数据[data.Date.dt.year.between(2012015)]数据.Date=data.Date.dt.year sns.box图(y='average age',x='Date',hue='Region',data=data)
我认为要获得更好的性能,最好先删除不必要的数据,然后再删除
groupby
——一般来说,数据处理越少,性能越好。你怎么看?我完全同意。我正要进一步编辑。是否先检查其他问题(-:
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
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