pandas groupby 和rolling_apply 忽略NaN

2024-04-10

我有一个 pandas 数据框,我想计算列的滚动平均值(在 groupby 子句之后)。但是,我想排除 NaN。

例如,如果 groupby 返回 [2, NaN, 1],则结果应为 1.5,而当前它返回 NaN。

我尝试了以下方法,但似乎不起作用:

df.groupby(by=['var1'])['value'].apply(pd.rolling_apply, 3,  lambda x: np.mean([i for i in x if i is not np.nan and i!='NaN']))

如果我尝试这样做:

df.groupby(by=['var1'])['value'].apply(pd.rolling_apply, 3,  lambda x: 1)

我在输出中得到 NaN,所以它一定与 pandas 在后台的工作方式有关。

有任何想法吗?

编辑: 这是我想要做的代码示例:

import pandas as pd
import numpy as np

df = pd.DataFrame({'var1' : ['a', 'b', 'a', 'b', 'a', 'b', 'a', 'b'], 'value' : [1, 2, 3, np.nan, 2, 3, 4, 1] })
print df.groupby(by=['var1'])['value'].apply(pd.rolling_apply, 2,  lambda x: np.mean([i for i in x if i is not np.nan and i!='NaN']))

结果是:

0    NaN
1    NaN
2    2.0
3    NaN
4    2.5
5    NaN
6    3.0
7    2.0

虽然我想要以下内容:

0    NaN
1    NaN
2    2.0
3    2.0
4    2.5
5    3.0
6    3.0
7    2.0

一如既往,在 pandas 中,坚持使用矢量化方法(即避免apply)对于性能和可扩展性至关重要。

您想要执行的操作有点繁琐,因为 groupby 对象上的滚动操作目前不支持 NaN(版本 0.18.1)。因此,我们需要几行短代码:

g1 = df.groupby(['var1'])['value']              # group values  
g2 = df.fillna(0).groupby(['var1'])['value']    # fillna, then group values

s = g2.rolling(2).sum() / g1.rolling(2).count() # the actual computation

s.reset_index(level=0, drop=True).sort_index()  # drop/sort index

这个想法是对窗口中的值求和(使用sum),计算 NaN 值(使用count)然后除以求均值。此代码提供以下与您所需的输出相匹配的输出:

0    NaN
1    NaN
2    2.0
3    2.0
4    2.5
5    3.0
6    3.0
7    2.0
Name: value, dtype: float64

在更大的 DataFrame(大约 100,000 行)上进行测试,运行时间低于 100 毫秒,比我尝试过的任何基于应用的方法都要快得多。

可能值得根据实际数据测试不同的方法,因为时间可能会受到其他因素(例如组数)的影响。不过,可以肯定的是,矢量化计算将会胜出。


上面显示的方法非常适合简单计算,例如滚动平均值。它将适用于更复杂的计算(例如滚动标准差),尽管实现更复杂。

总体思路是查看 pandas 中快速的每个简单例程(例如sum),然后用单位元素填充任何空值(例如0)。然后您可以使用 groupby 并执行滚动操作(例如.rolling(2).sum())。然后将输出与其他操作的输出组合。

例如,要实施groupby NaN 感知滚动方差(其中标准差是平方根)我们必须找到“平方的平均值减去平均值的平方”。这是它的草图:

def rolling_nanvar(df, window):
    """
    Group df by 'var1' values and then calculate rolling variance,
    adjusting for the number of NaN values in the window.

    Note: user may wish to edit this function to control degrees of
    freedom (n), depending on their overall aim.
    """
    g1 = df.groupby(['var1'])['value']
    g2 = df.fillna(0).groupby(['var1'])['value']
    # fill missing values with 0, square values and groupby
    g3 = df['value'].fillna(0).pow(2).groupby(df['var1'])

    n = g1.rolling(window).count()

    mean_of_squares = g3.rolling(window).sum() / n
    square_of_mean = (g2.rolling(window).sum() / n)**2
    variance = mean_of_squares - square_of_mean
    return variance.reset_index(level=0, drop=True).sort_index()

请注意,此函数可能在数值上不稳定(平方可能导致溢出)。熊猫用途韦尔福德算法 https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm内部来缓解这个问题。

不管怎样,这个函数虽然使用了几个操作,但是速度还是很快的。这是与建议的更简洁的基于应用的方法的比较亚基姆·皮罗任科 https://stackoverflow.com/a/37395589/3923281:

>>> df2 = pd.concat([df]*10000, ignore_index=True) # 80000 rows
>>> %timeit df2.groupby('var1')['value'].apply(\
         lambda gp: gp.rolling(7, min_periods=1).apply(np.nanvar))
1 loops, best of 3: 11 s per loop

>>> %timeit rolling_nanvar(df2, 7)
10 loops, best of 3: 110 ms per loop

在这种情况下,矢量化速度快了 100 倍。当然,根据您拥有多少数据,您可能希望坚持使用apply因为它允许您以牺牲性能为代价来实现通用性/简洁性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pandas groupby 和rolling_apply 忽略NaN 的相关文章

随机推荐

  • 将接口方法作为参数传递

    Note 这很可能是非常C 特定语言问题 与以下无关WCF or web services at all 有3方ASMXWeb 服务 用于数据检索 我创建了一个名为的通用方法ExecuteCommand 用于针对 Web 服务的每个请求 该
  • FSharp.Data.JsonProvider - 从类型获取 json

    FSharp Data JsonProvider 提供了一种从 json 转换为 F 类型的方法 是否可以反向操作 即声明 FSharp Data JsonProvider 创建的类型之一的实例 将字段值设置为我需要的值 然后获取等效的 j
  • Pyenv 不自动激活

    我已经在我的环境中安装了 pyenv 直到这个周末 当我安装 Kivy 时 我的 pyenv 本地设置一直工作正常 但是现在 当我进入各个 python 项目目录时 pyenv 不会自动正确激活正确的 python 版本 E g 我像这样使
  • Spring Security 与 AcceptHeaderLocaleResolver 和 i18n

    我陷入困境 可能错过了文档中的某些内容或犯了一些小错误 Spring Security 3 0 5 已集成到我的 Spring MVC 3 0 5 应用程序中 AcceptHeaderLocaleResolver用于区域设置检测 除了安全错
  • Angular JS 2 npm 和 ng(Angular-Cli) 之间的区别(内置工具)

    在 AngularJS 2 中 NPM 和 NG Angular CLI 之间的主要区别是什么 如果通过 NPM 如果我们可以构建我们的应用程序并且它可以工作 那么 NG 构建 Angular cli 的需求是什么 npm start 与
  • SQLite3 .backup 和 .dump 命令是否锁定数据库?

    我能找到的唯一文档 backup and dump是由 help backup DB FILE Backup DB default main to FILE dump TABLE Dump the database in an SQL te
  • 使用泛型快速查找给定类的超级视图

    我想我正在与仿制药作斗争 我想创建简单的 UIView 扩展来递归地查找函数参数中传递的类的超级视图 我希望该函数返回可选的 显然包含 nil 或作为提供的类的实例可见的对象 extension UIView func superviewO
  • 强制 Internet Explorer 使用特定的 Java 运行时环境安装?

    当查看别人包含小程序的网页时 当我安装了多个 JRE 时 如何强制 Internet Explorer 6 0 使用特定的 JRE 首先 禁用当前安装的 Java 版本 要执行此操作 请转至控制面板 gt Java gt 高级 gt 浏览器
  • 没有要加载的文件——rest_client (Rails 3)

    当我做thin start 这是我得到的错误 thin start gt gt Using rack adapter rvm gems ruby 1 9 2 p0 gems activesupport 3 0 9 lib active su
  • 尾递归函数上的 StackOverflowError

    当我使用 avg bids 4000 10 5 调用以下 Clojure 代码时 会导致 java lang StackOverflowError 我试图找出原因 因为 sum bids 是作为尾递归函数编写的 所以应该可以工作 使用 Cl
  • 如何允许 html 返回 angular2 管道?

    我有一个返回 html 字符串的管道 但是字符串输出可能会作为安全默认值进行转义 我确信必须有一个选项来允许使用 html 但当我搜索文档时找不到它 我怎样才能告诉管道允许渲染实际的 html 使用绑定innerHTML https dev
  • 转换 boost::variant 类型的 std::vector

    我如何实现下面的函数来从矢量转换Value to a Container 我想断言 如果不是所有成员values属于相同类型 即向量包含字符串和整数的混合 这是因为该函数的返回值是std vector
  • 发布签名的 Android 应用程序,Google Plus 登录和 Google 地图无法正常工作

    1 我正在使用谷歌 登录 and 谷歌地图在我的android应用程序中 2 在调试应用程序时从Android Studio到真实设备 移动 Google plus登录和Google Map工作正常 一切正常 Problem 1 Build
  • 检查 Ember Handlebar If 块助手中的值是否等于

    我们如何检查值是否相等ember js http www emberjs com的 If 块助手 if person John 我们如何在车把上执行上述操作 The if helper 只能测试属性 不能测试任意表达式 因此 在这种情况下
  • 在nodeJs socket.io中,webstorm中的方法未解决

    我正在节点中学习socket io 并且我已经使用 安装了该模块 npm install socket io save 这是我的代码 var app require express var http require http Server
  • 使用 Maven 3 设置 Struts2 EAR 项目

    我正在迁移自Apache Ant Apache Ivy to Apache Maven用于新项目的生命周期管理 我从未在正式版本中使用过 Maven 所以我对此完全是新手 目前我已经安装并配置Maven 3 http maven apach
  • 静态变量与成员

    如果某个类的数据将被修改并且需要在整个程序中保留 但仅在一个成员函数中使用 那么最好将该变量设为其所在例程的局部静态变量 还是使其成为该例程的局部静态变量 班级成员 问题不是 数据将在整个程序中使用 而是 如果您创建此类的两个对象 您是否希
  • 使用 nltk 中的meteor_score模块评估模型时如何实现meteor分数?

    我目前有 2 个文件 reference txt 和 model txt 这两个文本文件包含原始字幕和训练后生成的字幕 我可以简单地执行以下操作来获取流星分数 score nltk translate meteor score meteor
  • 如何以MVVM模式加载wpf用户控件

    我正在创建一个采用 mvvm 模式的 wpf 用户控件 所以我们有 视图 代码隐藏文件中没有代码 视图模型 模型 数据访问文件 I have 主窗口 xaml 作为视图文件 我需要与之绑定主窗口模型 cs 通常 在 wpf 应用程序中 我们
  • pandas groupby 和rolling_apply 忽略NaN

    我有一个 pandas 数据框 我想计算列的滚动平均值 在 groupby 子句之后 但是 我想排除 NaN 例如 如果 groupby 返回 2 NaN 1 则结果应为 1 5 而当前它返回 NaN 我尝试了以下方法 但似乎不起作用 df