我有一个数据框如下所示:
index value
2003-01-01 00:00:00 14.5
2003-01-01 01:00:00 15.8
2003-01-01 02:00:00 0
2003-01-01 03:00:00 0
2003-01-01 04:00:00 13.6
2003-01-01 05:00:00 4.3
2003-01-01 06:00:00 13.7
2003-01-01 07:00:00 14.4
2003-01-01 08:00:00 0
2003-01-01 09:00:00 0
2003-01-01 10:00:00 0
2003-01-01 11:00:00 17.2
2003-01-01 12:00:00 0
2003-01-01 13:00:00 5.3
2003-01-01 14:00:00 0
2003-01-01 15:00:00 2.0
2003-01-01 16:00:00 4.0
2003-01-01 17:00:00 0
2003-01-01 18:00:00 0
2003-01-01 19:00:00 3.9
2003-01-01 20:00:00 7.2
2003-01-01 21:00:00 1.0
2003-01-01 22:00:00 1.0
2003-01-01 23:00:00 10.0
索引是日期时间,并且列中记录了每小时的降雨量值(单位:mm),我想计算“平均湿法持续时间”,这意味着 一天中存在值(非零)的连续小时数的平均值,因此计算为
2 + 4 + 1 + 1 + 2 + 5 / 6 (events) = 2.5 (hr)
和“平均湿法施放量”,表示一天中连续小时值的平均值。
{ (14.5 + 15.8) + ( 13.6 + 4.3 + 13.7 + 14.4 ) + (17.2) + (5.3) + (2 + 4)+ (3.9 + 7.2 + 1 + 1 + 10) } / 6 (events) = 21.32 (mm)
上面的数据名称只是一个例子,我有更长时间序列的数据帧(例如超过一年),我如何编写一个函数,以便能够以更好的方式计算上面提到的两个值?提前谢谢!
P.S。值可能是NaN,我想忽略它。
答案 0 :(得分:2)
我不确定你要求的是什么。但是,我认为你所要求的是resample()
。如果我误解了你的问题,请纠正我。
从Creating pandas dataframe with datetime index and random values in column开始,我创建了一个随机时间序列数据帧。
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(1), freq='H')
np.random.seed(seed=1111)
data = np.random.randint(1, high=100, size=len(days))
df = pd.DataFrame({'Day': days, 'Value': data})
df = df.set_index('Day')
查看数据框
Day Value
2018-03-18 20:18:08.205546 29
2018-03-18 21:18:08.205546 56
2018-03-18 22:18:08.205546 82
2018-03-18 23:18:08.205546 13
2018-03-19 00:18:08.205546 35
2018-03-19 01:18:08.205546 53
2018-03-19 02:18:08.205546 25
2018-03-19 03:18:08.205546 23
2018-03-19 04:18:08.205546 21
2018-03-19 05:18:08.205546 12
2018-03-19 06:18:08.205546 15
2018-03-19 07:18:08.205546 9
2018-03-19 08:18:08.205546 13
2018-03-19 09:18:08.205546 87
2018-03-19 10:18:08.205546 9
2018-03-19 11:18:08.205546 63
2018-03-19 12:18:08.205546 62
2018-03-19 13:18:08.205546 52
2018-03-19 14:18:08.205546 43
2018-03-19 15:18:08.205546 77
2018-03-19 16:18:08.205546 95
2018-03-19 17:18:08.205546 79
2018-03-19 18:18:08.205546 77
2018-03-19 19:18:08.205546 5
2018-03-19 20:18:08.205546 78
现在,重新采样数据帧
# resample into 2 hours and drop the NaNs
df.resample('2H').mean().dropna()
它给你,
Day Value
2018-03-18 20:00:00 42.5
2018-03-18 22:00:00 47.5
2018-03-19 00:00:00 44.0
2018-03-19 02:00:00 24.0
2018-03-19 04:00:00 16.5
2018-03-19 06:00:00 12.0
2018-03-19 08:00:00 50.0
2018-03-19 10:00:00 36.0
2018-03-19 12:00:00 57.0
2018-03-19 14:00:00 60.0
2018-03-19 16:00:00 87.0
2018-03-19 18:00:00 41.0
2018-03-19 20:00:00 78.0
同样,你可以重新采样到我留给你的日,小时,分钟等。您可能需要查看
答案 1 :(得分:2)
我相信这就是你要找的东西。我已经为每个步骤的代码添加了解释。
# create helper columns defining contiguous blocks and day
df['block'] = (df['value'].astype(bool).shift() != df['value'].astype(bool)).cumsum()
df['day'] = df['index'].dt.normalize()
# group by day to get unique block count and value count
session_map = df[df['value'].astype(bool)].groupby('day')['block'].nunique()
hour_map = df[df['value'].astype(bool)].groupby('day')['value'].count()
# map to original dataframe
df['sessions'] = df['day'].map(session_map)
df['hours'] = df['day'].map(hour_map)
# calculate result
res = df.groupby(['day', 'hours', 'sessions'], as_index=False)['value'].sum()
res['duration'] = res['hours'] / res['sessions']
res['amount'] = res['value'] / res['sessions']
<强>结果强>
day sessions duration value amount
0 2003-01-01 6 2.5 127.9 21.316667