大Pandas每日气候学

2024-06-13 17:43:43 发布

您现在位置:Python中文网/ 问答频道 /正文

        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')

我希望输出没有多索引。你知道吗


Tags: to数据方法iddfdatetimeindex平均值
2条回答

如果我理解正确,您需要创建一个分类索引来分组。我选择用'%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, 01Aug, 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]

我认为您需要分配到新列:

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

你知道吗-

transformaggregation之间的区别:

#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

^{}用于原始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

但是,如果输出df^{}聚合大小发生了变化,但其他列不在输出中(如果需要,则需要按^{}聚合每个列):

df.dates = pd.to_datetime(df.dates)
df1 = df.groupby([df.dates.dt.month, df.dates.dt.day])['vi'].mean()
        .rename_axis(('months', 'days')).reset_index()
print (df1)
   months  days        vi
0       7     7  0.545235
1       7     9  0.531477
2       7    11  0.515362

相关问题 更多 >