在python中按特定年份对数据进行分组
Posted
技术标签:
【中文标题】在python中按特定年份对数据进行分组【英文标题】:Grouping data by specific years in 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 年之间?
【问题讨论】:
【参考方案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)
以上是关于在python中按特定年份对数据进行分组的主要内容,如果未能解决你的问题,请参考以下文章