使用pands.rolling方法实现移动窗口的聚合计算

一个问题举例

假设有一个5天的收益数据,需要每3天求出一次平均值来达成某个需求:

daterevenue
2023-05-0110
2023-05-0220
2023-05-0330
2023-05-0440
2023-05-0550

1号、2号和3号的数据求一次平均值,2号、3号和4号的数据求一次平均值,3号、4号和5号的数据求一次平均值,这样的需求该如何计算?

pandas的Series有一个rolling方法,用来专门解决这种移动窗口聚合运算问题,举个简单的使用例子:

import pandas as pd


series = pd.Series([10, 20, 30, 40, 50])

amount = series.rolling(3).mean()

print(amount)

输出如下

0     NaN
1     NaN
2    20.0
3    30.0
4    40.0
dtype: float64

pd.rolling简单示例
可以看到需求确实如我们所需要的,但是你可能又会说,前两个均值不应该是NaN,少于1天的时候求均值就使用已有天数的数据来计算,别担心,此时只需要指定rolling的参数min_period为1即可:

import pandas as pd


series = pd.Series([10, 20, 30, 40, 50])


amount = series.rolling(3, min_periods=1).mean()	# min_period可以指定窗口计算所需要最少的元素,这个值必须小于等于第一个参数窗口的大小3

print(amount)
0    10.0
1    15.0
2    20.0
3    30.0
4    40.0
dtype: float64

结果完美满足需求

然后欠缺考虑周全的产品可能又会跟你说,这里除了求均值,还想给它求个总和,既然都支持求均值了,当然聚合计算都得带上,
rolling方法后面还可以跟上使用求和、最大最小值、均值、方差等常用的聚合方法,除此之外,甚至可以使用agg自定义聚合函数,只要agg返回的值是一个数值:

import pandas as pd


series = pd.Series([10, 20, 30, 40, 50])
amount = series.rolling(3, min_periods=1).agg(lambda x: x.loc[x > 20].sum())    # x就是一个Series,x.loc[x > 20]表示取这个series中大于20的数求和

print(amount)
0      0.0
1      0.0
2     30.0
3     70.0
4    120.0
dtype: float64

rolling方法的进一步介绍

rolling中还有一个center参数,可以指定移动窗口的中心位置作为基准对数据执行计算,center默认为False表示当前数据作为窗口的最后一个数作为基准选取计算的区域,为True的时候将以当前数据作为窗口的中心位置作为基准选取数据执行计算:
在这里插入图片描述
窗口大小是奇数时,如上图一样上下各平分一般窗口计算区域,如果窗口大小是偶数,上半窗口会多多一个数,比如窗口是4,那么上半区域是2个数,下半区域是1个数,加上自身一共4个数

rolling还可以支持对时间段窗口区域进行分析,这十分契合具体的使用场景,例如需求是统计一个在发生某初始化事件(initial)当天往后1天内发生消费(paid)数额超过30的数据:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    np.array([
        ["a", "a", "b", "c", "d", "d"],
        [np.nan, 10, 20, 30, np.nan, 50],
    ]).T,
    index=pd.Index(pd.to_datetime(["2023-04-30", "2023-05-01", "2023-05-02", "2023-05-03", "2023-05-04", "2023-05-05"]), name="date"),
    columns=["uid", "paid"]
)

print(df)

#            uid  paid
# date
# 2023-04-30   a   NaN
# 2023-05-01   a  10.0
# 2023-05-02   b  30.0
# 2023-05-03   c  60.0
# 2023-05-04   d  50.0
# 2023-05-05   d  80.0


df["paid"] = df["paid"].rolling(
    "3D"
).sum()
print(df)

#            uid  paid
# date
# 2023-04-30   a   NaN
# 2023-05-01   a  10.0
# 2023-05-02   b  30.0
# 2023-05-03   c  60.0
# 2023-05-04   d  50.0
# 2023-05-05   d  80.0

df = df.where(lambda x: x["paid"] > 30).dropna().reset_index()
print(df)

#         date uid  paid
# 0 2023-05-03   c  60.0
# 1 2023-05-04   d  50.0
# 2 2023-05-05   d  80.0

支持指定时间窗口的条件:
index必须是python的时间类型
有关第一个参数的时间字符串表示,可以参考官方的这个链接:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases

如果想让当前的数据作为窗口的开头怎么使用?

from pandas.api.indexers import FixedForwardWindowIndexer

使用FixedForwardWindowIndexer方法,指定window_size即可,具体使用方法及更多相关的窗口函数方法,可以参考官网给的说明:https://docs.scipy.org/doc/scipy/reference/signal.windows.html#module-scipy.signal.windows

实践中可能会遇到问题

计算的数值中有nan,而且需要把这些nan放到窗口计算中?
很简单,只需要把series中的nan替换成0即可:

import numpy as np
import pandas as pd

series = pd.Series([10, 20, 30, np.nan, 50])

series.replace(np.nan, 0, inplace=True)

amount = series.rolling(3, min_periods=1).mean()

print(amount)
# 输出
# 0    10.000000
# 1    15.000000
# 2    20.000000
# 3    16.666667
# 4    26.666667
# dtype: float64

那如果有一部分的无效数值需要保留,有一部分不需要,该如何处理?
比如,需求是2023-05-01之前的值不能参与计算,且你在一次处理中不能或不方便直接删除掉2023-05-01之前的数据:

import numpy as np
import pandas as pd

series = pd.Series([np.nan, 10, 20, 30, np.nan, 50]).replace(np.nan, 0)


series.index = pd.to_datetime(["2023-04-30", "2023-05-01", "2023-05-02", "2023-05-03", "2023-05-04", "2023-05-05"])
print(series)

# 2023-04-30     0.0
# 2023-05-01    10.0
# 2023-05-02    20.0
# 2023-05-03    30.0
# 2023-05-04     0.0
# 2023-05-05    50.0
# dtype: float64


# 对于不能把2023-05-01之前的数据计算时直接删除时,可以先替换成特殊值
series = series.where(
    lambda col:
    col.index >= pd.to_datetime("2023-05-01"), "invalid"
)       # where第一个参数是给定符合的条件,这一部分数据不会变化,第二个参数是不符合第一个条件的数据会被替换成的值

print(series.loc[series != "invalid"])

# 2023-05-01    10.0
# 2023-05-02    20.0
# 2023-05-03    30.0
# 2023-05-04     0.0
# 2023-05-05    50.0
# dtype: object


# 然后计算时只排除特殊值
amount = series.loc[series != "invalid"].rolling(3, min_periods=1).mean()	  # rolling的mean方法计算时会尝试把数据转成数值来执行计算

print(amount)

# 2023-05-01    10.000000
# 2023-05-02    15.000000
# 2023-05-03    20.000000
# 2023-05-04    16.666667
# 2023-05-05    26.666667
# dtype: float64

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/15850.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5.4.1树的存储结构 5.4.2树和森林的遍历

回忆一下树的逻辑结构: 双亲表示法(顺序存储) 如果增加一个结点M,L。毋须按照逻辑上的次序存储。 如果是删除元素: 方案一:比如说删除元素为G,设置其双亲结点为-1。 方案二: 把尾部的结点提上…

Sybase使用sp_helptext查看系统存储过程的源码

sp_helptext存储过程用于显示已编译对象的源代码。 sp_helptext是Sybase ASE内置的存储过程,可从任何位置调用。 但实际上,如果直接使用,常常会得到(令人头大的)错误提示: Msg 17461 Object does not exi…

基于JavaSpringboot+vue国风汉服文化交流宣传系统

基于JavaSpringbootvue国风汉服文化交流宣传系统 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目…

【可解释AI】图神经网络的可解释性方法及GNNexplainer代码示例

图神经网络的可解释性方法及GNNexplainer代码示例 GNNExplainerIntroductionModelSingle-instance explanations(Explanation via Structural Information)Joint learning of graph structural and node feature information(Explanation via…

SuperMap iClient3D for Cesium 构建隧道

作者:kele 背景 前段时间看到一篇构建隧道的文章(https://blog.csdn.net/supermapsupport/article/details/128453116),突然想到一个使用场景:隧道通常是建在山体下面,是否可以通过这种方式构建出一条贯穿…

使用Python和机器学习进行文本情感分类

使用Python和机器学习进行文本情感分类 1. 效果图2. 原理3. 源码参考这篇博客将介绍如何使用Python进行机器学习的文本情感分类(Text Emotions Classification)。 1. 效果图 训练文本及情感分类前5条数据如下: 训练过程及测试文本情感分类效果图如下: 可以看到 对文本“S…

【量化交易笔记】5.SMA,EMA 和WMA区别

股票中的SMA,EMA和WMA是常用的技术分析指标。这些指标基于历史股价计算得出,可以帮助投资者了解股票的趋势,为决策提供依据。虽然它们都是平均值算法,但它们之间还是有一些区别的。 SMA 简单移动平均线(Simple Moving…

分布式的流处理平台Kafka

目录: 一、简介二、基本概念三、生产者使用详解四、发送消息五、消费者代码示例 一、简介 ApacheKafka 是一个分布式的流处理平台。它具有以下特点: 支持消息的发布和订阅,类似于 RabbtMQ、ActiveMQ 等消息队列;支持数据实时处理…

计算机组成原理第五章(2)---中断

5.1概述 产生和应用 在IO设备和主机交换数据时,由于设备本身的机电特性的影响,其工作速度比较低,与CPU无法匹配,如果采用程序查询的方式需要CPU进行等待,但是如果在等待的过程中CPU可以执行其他的程序,可…

【@Param注解】| 台面使用——>底层原理分析

🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 目录 🦁 定义🦁 台面使用🦁 底层原理分析🦁 尾声🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄…

java实现乘法的方法

我们都知道,乘法运算的核心思想就是两个数相乘,如果能将乘法运算转化成一个加数的运算,那么这个问题就很容易解决。比如我们要实现23的乘法,首先需要定义两个变量:2和3。我们将这两个变量定义为一个变量:2x…

PySide6/PyQT多线程之 信号与槽 / (Signal Slot)的高效利用

前言 PySide6/PyQT信号槽是一种事件处理方式,允许程序中的对象发送和接收信号。 在 PySide6/PyQT 精进的过程中,一定躲不开 信号和槽 这座大山,这是一个比较有意思的知识点: 初接触的看不懂,觉得复杂;看得…

本地 WAF 已死,云 WAF 永生

多年来,Web 应用程序防火墙 (WAF) 一直是应用程序保护的代名词。事实上,许多应用程序安全团队认为保护其应用程序的最佳选择是一流的本地 WAF 解决方案,尤其是当这些应用程序部署在本地或私有云中时。 但自从引入本地 WAF 以来,…

JMeter的使用(二)

九、直连数据库 通过直连数据库让程序代替接口访问数据库,如果二者预期结果不一致,就找到了程序缺陷。 获取某条学院的名字,放在百度搜索: JMeter 不具备直连数据库功能,必须整合第三方(jar包)实现配置数据库的连接通过JDBC Re…

@PostConstruct注解和@PreDestroy注解

前言 Bean注解指定初始化和销毁的方法,也介绍了使用InitializingBean和DisposableBean来处理bean的初始化和销毁。JDK中还提供了两个注解能够在bean创建完成并且属性赋值完成之后执行一些初始化工作和在容器销毁bean之前通知我们进行一些清理工作。 1.PostConstru…

LDAP概念和原理介绍

LDAP概念和原理介绍 相信对于许多的朋友来说,可能听说过LDAP,但是实际中对LDAP的了解和具体的原理可能还比较模糊,今天就从“什么是LDAP”、“LDAP的主要产品”、“LDAP的基本模型”、“LDAP的使用案例”四个方面来做一个介绍。 我们在开始…

有什么牌子台灯性价比高?性价比最高的护眼台灯

由心感叹现在的孩子真不容易,学习压力比我们小时候大太多,特别是数学,不再是简单的计算,而更多的是培养学生其他思维方式,有时候我都觉得一年级数学题是不是超纲了。我女儿现在基本上都是晚上9点30左右上床睡觉&#x…

自动拣货仓库亮灯方案

方案目标概叙: 系统在美团平台下单后,骑手会收到取货码,凭借取货码到指定的智能仓库去取货,仓库标签系统调取相应订单信息,执行亮灯指令(屏幕显示订单信息及拣货数量,并亮灯)&#…

【MySQL】存放页面的大池子——InnoDB的表空间

概念: 页: 是InnoDB存储引擎管理数据库的最小磁盘单位,一个页的大小一般是16KB。一次至少读取一页的数据到内存,或者刷新一页的数据到磁盘。数据页:FIL_PAGE_INDEX类型的页,B树中的节点就是数据页。区&…

Elasticsearch --- 索引库、文档操作

一、索引库操作 索引库就类似数据库表,mapping映射就类似表的结构。 我们要向es中存储数据,必须先创建“库”和“表”。 1.1、mapping映射属性 mapping是对索引库中文档的约束,常见的mapping属性包括: type:字段数据…