id vi dates f_id
0 5532714 0.549501 2015-07-07 ff_22
1 5532715 0.540969 2015-07-08 ff_22
2 5532716 0.531477 2015-07-09 ff_22
3 5532717 0.521029 2016-07-09 ff_22
4 5532718 0.509694 2017-07-11 ff_22
在上面的数据框中,我想计算气候学,即跨越多年的数据帧的每日平均值。目前我试过这个:
df.index = pd.to_datetime(df.dates)
df.groupby([df.index.month, df.index.day])['vi'].transform('mean')
我希望输出没有多索引。
答案 0 :(得分:3)
如果我理解正确,您需要创建分组索引以进行分组。我选择使用'%b, %d'
格式化日期,但您可以使用strftime.org选项中的任何月/日组合。
考虑由4年随机每日数据组成的数据框df
:
tidx = pd.date_range('2010-01-01', '2013-12-31', name='dates')
np.random.seed([3,1415])
df = pd.DataFrame(dict(vi=np.random.rand(tidx.size)), tidx)
我会选择从2012
制作我的类别标签,因为它是闰年,并且会包含Feb 29
。通过创建类别,大熊猫将知道Jan, 01
之前的Aug, 31
。
fmt = '%b, %d'
categories = pd.CategoricalIndex(
df.index.strftime(fmt),
pd.date_range('2012-01-01', '2012-12-31').strftime(fmt)
)
df.groupby(categories).mean()
vi
Jan, 01 0.452812
Jan, 02 0.422205
Jan, 03 0.409369
Jan, 04 0.620173
Jan, 05 0.456044
Jan, 06 0.616172
Jan, 07 0.693760
Jan, 08 0.636427
Jan, 09 0.490981
Jan, 10 0.412720
Jan, 11 0.516009
Jan, 12 0.372129
... ...
Dec, 20 0.523669
Dec, 21 0.372038
Dec, 22 0.609447
Dec, 23 0.568481
Dec, 24 0.612216
Dec, 25 0.765035
Dec, 26 0.368508
Dec, 27 0.558909
Dec, 28 0.371733
Dec, 29 0.516978
Dec, 30 0.654397
Dec, 31 0.793721
[366 rows x 1 columns]
答案 1 :(得分:2)
我认为您需要分配到新列:
df.index = pd.to_datetime(df.dates)
df['new'] = df.groupby([df.index.month, df.index.day])['vi'].transform('mean')
print (df)
id vi dates f_id new
dates
2015-07-07 5532714 0.549501 2015-07-07 ff_22 0.549501
2015-07-08 5532715 0.540969 2015-07-08 ff_22 0.540969
2015-07-09 5532716 0.531477 2015-07-09 ff_22 0.526253
2016-07-09 5532717 0.521029 2016-07-09 ff_22 0.526253
2017-07-11 5532718 0.509694 2017-07-11 ff_22 0.509694
df.index = pd.to_datetime(df.dates)
df = df.assign(new=df.groupby([df.index.month, df.index.day])['vi'].transform('mean'))
print (df)
id vi dates f_id new
dates
2015-07-07 5532714 0.549501 2015-07-07 ff_22 0.549501
2015-07-08 5532715 0.540969 2015-07-08 ff_22 0.540969
2015-07-09 5532716 0.531477 2015-07-09 ff_22 0.526253
2016-07-09 5532717 0.521029 2016-07-09 ff_22 0.526253
2017-07-11 5532718 0.509694 2017-07-11 ff_22 0.509694
然后在必要时reset_index
:
df = df.reset_index(drop=True)
print (df)
id vi dates f_id new
0 5532714 0.549501 2015-07-07 ff_22 0.549501
1 5532715 0.540969 2015-07-08 ff_22 0.540969
2 5532716 0.531477 2015-07-09 ff_22 0.526253
3 5532717 0.521029 2016-07-09 ff_22 0.526253
4 5532718 0.509694 2017-07-11 ff_22 0.509694
但将列date
转换为datetime
似乎更好,然后reset_index
不是必需的:
df.dates = pd.to_datetime(df.dates)
df['new'] = df.groupby([df.dates.dt.month, df.dates.dt.day])['vi'].transform('mean')
print (df)
id vi dates f_id new
0 5532714 0.549501 2015-07-07 ff_22 0.549501
1 5532715 0.540969 2015-07-08 ff_22 0.540969
2 5532716 0.531477 2015-07-09 ff_22 0.526253
3 5532717 0.521029 2016-07-09 ff_22 0.526253
4 5532718 0.509694 2017-07-11 ff_22 0.509694
如果由于某种原因无法将列转换为datetime
,则可以使用:
d = pd.to_datetime(df.dates)
df['new'] = df.groupby([d.dt.month, d.dt.day])['vi'].transform('mean')
print (df)
id vi dates f_id new
0 5532714 0.549501 2015-07-07 ff_22 0.549501
1 5532715 0.540969 2015-07-08 ff_22 0.540969
2 5532716 0.531477 2015-07-09 ff_22 0.526253
3 5532717 0.521029 2016-07-09 ff_22 0.526253
4 5532718 0.509694 2017-07-11 ff_22 0.509694
transform
和aggregation
之间的差异:
#changed sample data - dates
print (df)
id vi dates f_id
0 5532714 0.549501 2015-07-07 ff_22
1 5532715 0.540969 2016-07-07 ff_22
2 5532716 0.531477 2015-07-09 ff_22
3 5532717 0.521029 2016-07-11 ff_22
4 5532718 0.509694 2017-07-11 ff_22
GroupBy.transform
用于原始DataFrame
中的新列 - 输出df
的大小未更改,因此相同组的数据相同:
df.dates = pd.to_datetime(df.dates)
df['new'] = df.groupby([df.dates.dt.month, df.dates.dt.day])['vi'].transform('mean')
print (df)
id vi dates f_id new
0 5532714 0.549501 2015-07-07 ff_22 0.545235
1 5532715 0.540969 2016-07-07 ff_22 0.545235
2 5532716 0.531477 2015-07-09 ff_22 0.531477
3 5532717 0.521029 2016-07-11 ff_22 0.515362
4 5532718 0.509694 2017-07-11 ff_22 0.515362
但是,如果输出GroupBy.mean
输出agg
的大小已更改,但输出中没有其他列(如果需要,则需要按here聚合每列):
df