DataFrame降采样的定制化处理(resample的用户定义函数)

DataFrame重采样的定制化处理

对于时间序列数据,有时候我们期望的采样间隔和实际的采样间隔不一致,将采样频率较高的数据汇总处理成采样频率较低的数据的过程称为降采样,在Pandas中通过df.resample()实现。

降采样首先需要指定采样频率,将原数据按目标频率划分成若干序列,并对序列中的数据进行一定操作,生成目标频率下的表征值。

Pandas提供了包括求和、均值、方差等在内的常规方法用于计算表征值,这些方法通常能满足绝大多数的应用场景,但有时候,尤其是数据中存在缺失值的情况下,用常规方法计算出的表征值可能不够合理。此时,用户可以定义一个函数来处理采样序列的数据,以使表征值达到想要的效果。

下面是一个示例场景:假设处理高速公路检测器流量数据,原始数据每30s收集一次,数据有缺失情况。现考虑统计每2min的流量总和:在每个2min的数据中,如果缺失2个以内数据,就用均值补全再求和;否则,认为这2min的数据缺失。

首先构造数据集

# 生成20个数据点
index = pd.date_range('1/1/2000 00:00:00', periods=20, freq='30s')
series = pd.Series(range(20), index=index)
# 设置一些缺失值
series.iloc[[1,5,6,7,-1,-2,-3,-4]] = np.nan
series
Out[16]: 
2000-01-01 00:00:00     0.0
2000-01-01 00:00:30     NaN
2000-01-01 00:01:00     2.0
2000-01-01 00:01:30     3.0
2000-01-01 00:02:00     4.0
2000-01-01 00:02:30     NaN
2000-01-01 00:03:00     NaN
2000-01-01 00:03:30     NaN
2000-01-01 00:04:00     8.0
2000-01-01 00:04:30     9.0
2000-01-01 00:05:00    10.0
2000-01-01 00:05:30    11.0
2000-01-01 00:06:00    12.0
2000-01-01 00:06:30    13.0
2000-01-01 00:07:00    14.0
2000-01-01 00:07:30    15.0
2000-01-01 00:08:00     NaN
2000-01-01 00:08:30     NaN
2000-01-01 00:09:00     NaN
2000-01-01 00:09:30     NaN
Freq: 30S, dtype: float64

首先看一下直接用sum的效果:

series_2min = series.resample('2min').sum()
series_2min
Out[17]: 
2000-01-01 00:00:00     5.0
2000-01-01 00:02:00     4.0
2000-01-01 00:04:00    38.0
2000-01-01 00:06:00    54.0
2000-01-01 00:08:00     0.0
Freq: 2T, dtype: float64

显然这是直接对每4个数据求和,nan被视为0,全部为nan的情况下认为和为0而不是nan,这不太合理。

我们可以通过用户自定义的函数来按合理的方法处理集计的数据。按如下方式定义和调用:

def custom_resampler(array_like):
    # 定义一个函数来处理resample后的每一部分数据
    no_of_nan = array_like.isnull().sum(axis=0)             # nan的个数
    lens = len(array_like)                                  # 总元素个数
    if no_of_nan/lens>=0.5:                                 # 如果nan占了五成以上
        return_value = np.nan                               # 返回nan
    else:
        # 否则用均值填充缺失值,并返回和
        array_like[array_like.isnull()] = array_like.mean()
        return_value = array_like.sum()
    return return_value

series_2min = series.resample('2min').apply(custom_resampler)
series_2min
Out[20]: 
2000-01-01 00:00:00     6.666667
2000-01-01 00:02:00          NaN
2000-01-01 00:04:00    38.000000
2000-01-01 00:06:00    54.000000
2000-01-01 00:08:00          NaN
Freq: 2T, dtype: float64

通过定义custom_resampler函数并用.apple(custom_resampler)调用,实现了我们的目标,在默认方法无法满足我们的需求时,自定义的方法很好用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值