对多列进行 GroupBy 并应用移动功能

2024-04-02

假设我有这个数据集:

Country_id  Company_id  Date    Company_value
1   1   01/01/2018  1
1   1   02/01/2018  0
1   1   03/01/2018  2
1   1   04/01/2018  NA
1   2   01/01/2018  1
1   2   02/01/2018  2
1   2   03/01/2018  NA
1   2   04/01/2018  NA
2   1   01/01/2018  3
2   1   02/01/2018  0
2   1   03/01/2018  2
2   1   04/01/2018  NA
2   2   01/01/2018  1
2   2   02/01/2018  2
2   2   03/01/2018  NA
2   2   04/01/2018  NA

我想应用移动函数(例如移动平均值)来检索每个日期和国家/地区的聚合值。

例如,在移动平均线的情况下(window = 2 & min_periods=1,NA 不计入),我希望有以下内容:

Country_id  Date    Companies_value
1   01/01/2018  1
1   02/01/2018  1
1   03/01/2018  1.33
1   04/01/2018  2
2   01/01/2018  2
2   02/01/2018  1.5
2   03/01/2018  1.33
2   04/01/2018  2

为了让您更容易,按以下方式计算:

Country_id  Date    Companies_value
1   01/01/2018  (1+1)/2
1   02/01/2018  (0+1+2+1)/4
1   03/01/2018  (2+0+2)/3
1   04/01/2018  (2)/1
2   01/01/2018  (3+1)/2
2   02/01/2018  (0+3+2+1)/4
2   03/01/2018  (2+0+2)/3
2   04/01/2018  (2)/1

我怎样才能做到这一点pandas?

用文字给出一个简短的例子,例如,我想要国家 1 在 2018 年 1 月 3 日的数据是取该国家在 2018 年 2 月 1 日和 03 月 1 日的所有公司价值的平均值/2018(窗口大小为2的情况)。

因此,这就是我希望在 2018 年 3 月 1 日为国家 1 做的事情:

( Company_value(Company_1, 03/01/2018) + Company_value(Company_1, 02/01/2018) 
+ Company_value(Company_2, 03/01/2018) + Company_value(Company_2, 02/01/2018) ) / 4 =

= ( 2 + 0 + NA + 2) / 4 

= ( 2 + 0 + 2) / 3 # NAs not counted in

= 1.33

类似地,我希望对每个国家/地区的所有日期执行相同的操作。

正如我所说,我想对我自己的移动函数做同样的事情,超越移动平均线pandas因此,最好提供一个对任何自定义函数都有效的解决方案。


更新了附加信息

data:

import pandas as pd
import numpy as np

df = pd.DataFrame({'date':['2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01']*4,
              'country_id':[1]*8+[2]*8,
              'company_id':[1]*4+[2]*4+[1]*4+[2]*4,
              'value':[1, 0, 2, np.nan, 1, 2, np.nan, np.nan, 3, 0, 2, np.nan, 1, 2, np.nan, np.nan]})

在短短时间内创建滚动总和country_id

df['rolling_sum'] = df.groupby('country_id').apply(lambda x: x.value.rolling(window=2, min_periods=1).sum()).reset_index(drop=True)

在短短时间内创建滚动计数country_id

df['sum_records'] = df.groupby('country_id').apply(lambda x: x.value.rolling(window=2, min_periods=1).count()).reset_index(drop=True)

现在 groupby 内country_id and date,对总和进行求和,然后除以计数总和

summarized_df = df.groupby(['country_id', 'date']).apply(lambda x: x.rolling_sum.sum()/x.sum_records.sum()).reset_index()

country_id  date      
1           2018-01-01    1.000000
            2018-02-01    1.000000
            2018-03-01    1.333333
            2018-04-01    2.000000
2           2018-01-01    2.000000
            2018-02-01    1.500000
            2018-03-01    1.333333
            2018-04-01    2.000000

让我们更详细地看看这个。由于我们按国家/地区 ID 进行分组,因此我们将提取单个国家/地区 ID 来实践此方法:

如果我们只取其中的一块,比如说country_id == 1:

df2 = df[df['country_id'] == 1]

         date  country_id  company_id  value
0  2018-01-01           1           1    1.0
1  2018-02-01           1           1    0.0
2  2018-03-01           1           1    2.0
3  2018-04-01           1           1    NaN
4  2018-01-01           1           2    1.0
5  2018-02-01           1           2    2.0
6  2018-03-01           1           2    NaN
7  2018-04-01           1           2    NaN

如果我们想要这个的滚动平均值,我们可以这样做:

df2.value.rolling(window=2, min_periods=1).mean()
0    1.0
1    0.5
2    1.0
3    2.0
4    1.0
5    1.5
6    2.0
7    NaN

我们可以在这里看到子集country_id == 1 数据帧中的值以及它们与滚动平均值的关系:

0    1.0  = (1)/1 = 1
1    0.0  = (0 + 1)/2 = 0.5
2    2.0  = (2 + 0)/2 = 1
3    NaN  = (Nan + 2)/1 = 2
4    1.0  = (1 + Nan)/1 = 1
5    2.0  = (2 + 1)/2 = 1.5
6    NaN  = (Nan + 2)/1 = 2
7    NaN  = (Nan + Nan)/0 = Nan

这就是我们获得单个分组的滚动平均值的方法country_id

If我们想要按日期进行分组,我们首先按country_id进行分组,然后按日期进行分组,单个组如下所示:

df3 = df[(df['country_id'] == 1) & (df['date'] == '2018-03-01')]

df3.value
2    2.0
6    NaN

df3.value.rolling(window=2, min_periods=1).mean()
2    2.0
6    2.0

df3.value
2    2.0 = (2)/1 = 2
6    NaN = (Nan + 2)/1 = 2

这里的问题是你想要滚动平均值first by country_id,不与分组date. Then找到按国家/地区划分的滚动平均值后,您想要采取those值并求平均值。如果我们要采取滚动averages, 进而average那些,结果会是错误的。

那么让我们回到我们创建的原始滚动平均值country_id == 1,然后查看日期:

2018-01-01    1.0  = (1)/1 =         1
2018-02-01    0.0  = (0 + 1)/2 =     0.5
2018-03-01    2.0  = (2 + 0)/2 =     1
2018-04-01    NaN  = (Nan + 2)/1 =   2
2018-01-01    1.0  = (1 + Nan)/1 =   1
2018-02-01    2.0  = (2 + 1)/2 =     1.5
2018-03-01    NaN  = (Nan + 2)/1 =   2
2018-04-01    NaN  = (Nan + Nan)/0 = Nan

现在这里棘手的部分是,此时我们不能只是将它们平均在一起,因为例如,如果您查看 2018-03-01 滚动平均值,我们有 1 和 2,即 3。将其除以 2 将得到我们1.5。

我们必须首先sum滚动值,然后除以记录数。

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

对多列进行 GroupBy 并应用移动功能 的相关文章

随机推荐

  • 在提取/替换操作期间保留对象属性的方法

    最近我在我的R代码中遇到了以下问题 在接受数据框作为参数的函数中 我需要添加 或替换 如果存在 一列 其中包含根据数据框原始列的值计算的数据 我编写了代码 但测试显示数据框提取 替换操作 我用过 结果是对象的特殊 用户定义 属性丢失 在意识
  • 使用 application/x-www-form-urlencoded 的 POST 请求

    后端开发人员在 POST 请求中给出了这些说明 路线 url app name controller action 控制器和操作应该是小写字母 API测试链接 http 请求应使用 POST 方法 参数应通过请求内容正文 FormUrlEn
  • 客户端语言

    我不是网络程序员 所以请原谅我的无知 当谈到服务器端编程时 我们有很多可用的技术 例如 PHP ASP net JSP 等 然而 说到客户端脚本 我只听说过 JavaScript 和 AJAX 也许您还可以包含 Java Applet 因为
  • 使用 PHP 将文件夹重命名为子文件夹

    我正在尝试通过重命名来移动文件夹 test1 和 test2 文件夹均已存在 rename test1 test2 xxx1 xxx2 我得到的错误是 重命名 没有这样的文件或目录 我认为这是因为目录 xxx1 不存在 我怎样才能移动 te
  • 大多数编译器都会优化 MATMUL(TRANSPOSE(A),B) 吗?

    In a Fortran program I need to compute several expressions like M v MT v MT M M MT etc Here M and v are 2D and 1D arrays
  • Scala:==默认等于吗?

    我正在阅读 Scala 编程 它说 您可以重新定义的行为 通过覆盖新类型equals方法 始终从类继承Any 继承的equals除非被覆盖 否则它是对象标识 就像 Java 中的情况一样 所以equals 随之而来的是 默认情况下与eq 但
  • 发布有关 Ektron 问题的最佳在线网站是什么?

    我正在尝试使用 Dotnet 在 Ektron 中做一个新项目 我发现数量相当少 stackoverflow 中发布的问题及其答复 最好的网站是什么 消除我在使用 Ektron 进行开发时的疑虑 谢谢 同意 zkent 但有额外的建议 发布
  • 尝试使用 Fluent NHibernate 调用存储过程时出现命名查询未知错误

    我正在为一个项目设置 NHibernate 并且有一些疑问 由于它们的复杂性 我们将保留为存储过程 我希望能够使用 NHibernate 来调用存储过程 但遇到了一个我无法弄清楚的错误 由于我使用的是 Fluent NHibernate 所
  • 使用WMI远程卸载应用程序

    我正在尝试编写一个迷你 w32 可执行文件来使用 WMI 远程卸载应用程序 我可以使用下面的代码列出所有已安装的应用程序 但我找不到通过 WMI 和 C 远程卸载应用程序的方法 我知道我可以使用 msiexec 作为进程来执行相同的操作 但
  • gradle 在哪里保存依赖项的 jar?

    我想查看添加依赖项时编译的 jars aars 例如 如果我在 Gradle 中添加此依赖项 它会将 jar 放在哪里 dependencies compile com google android gms play services an
  • 在knitr中跨行分割r块标题

    当我在 R 块标头中插入长标题等内容时 如果能够将标头拆分为多行 那就太好了 有什么简单的方法可以做到这一点吗 E g r echo FALSE warning FALSE fig cap Here is my really long ca
  • 关于“ls”,我如何只显示目录(链接目录和隐藏目录除外)

    我遇到一些关于 ls 这个命令的问题 我只想打印没有隐藏或链接的目录 但我用 man ls 查看解释 但没有找到 如果有一面旗帜表明我可以做我想做的事 thanks 下面是我要解决的问题 4 显示可见出口 This is two comma
  • 来自 Jenkins 的参考 Xcode 版本号

    我正在尝试在 Jenkins Build 中获取对 Xcode 项目 CFBundleVersionString 或 CFBundleVersion 的引用 我的目标是能够以这种方式设置内部版本号 CFBundleVersionString
  • Python 中 pickle 的常见用例

    我看过pickle http en wikipedia org wiki Pickle 28Python 29文档 但我不明白 pickle 在哪里有用 pickle 的一些常见用例有哪些 我遇到过的一些用途 1 将程序的状态数据保存到磁盘
  • 如何最大化和最小化div(没有jquery只有javascript)

    你好 我需要仅使用javascript而不是jquery来最大化或最小化我的html页面中的div 我希望能够这样做http jsfiddle net miqdad Qy6Sj 1 http jsfiddle net miqdad Qy6S
  • 如何在 winform 中托管带有 UI 的控制台 exe

    我正在开发一个具有某些特定要求的项目 我需要创建一个可以使用 C 监视并在其中运行 exe 的程序 然而 使用控制台程序来实际托管另一个exe的方法似乎没有尽头 所以我使用了WinForm 我一直在寻找并找到了一些非常好的解决方案 它在 W
  • 在PowerShell中获取PATH环境变量

    我想检查 PowerShell 中的 PATH 环境变量 我试过了 Get ChildItem env path 我想获得完整的路径 但只获得其中的很小一部分 我得到多少取决于 PowerShell 窗口的宽度 例如 C Program F
  • Google API 客户端机密错误 (Python)

    我想从 Google Analytics 检索数据 我已经在控制台中创建了一个服务帐户 并且我正在使用 Google 的 Python hello analytics api v3 py 代码来访问数据 我已经复制了client secre
  • Mac OS Cocoa:在画布上绘制一个简单的像素

    我希望我能找到这个问题的答案 我搜索了又搜索 找不到正确的答案 这是我的情况 在 Mac OS Cocoa 应用程序中 我想在应用程序窗口的专用区域上绘制一个像素 实际上是几个像素 我想 如果有一个就更好了NSImageView放置在那里
  • 对多列进行 GroupBy 并应用移动功能

    假设我有这个数据集 Country id Company id Date Company value 1 1 01 01 2018 1 1 1 02 01 2018 0 1 1 03 01 2018 2 1 1 04 01 2018 NA