0

0

如何使用Pandas在分组数据上正确计算滚动平均值

DDD

DDD

发布时间:2025-11-21 15:19:02

|

954人浏览过

|

来源于php中文网

原创

如何使用pandas在分组数据上正确计算滚动平均值

本文深入探讨了在Pandas中对分组数据计算滚动平均值时遇到的常见问题,特别是TypeError: incompatible index of inserted column with frame index错误以及结果不准确的情况。通过分析groupby().rolling().mean()操作产生的多级索引问题,文章详细介绍了如何利用droplevel()方法来解决索引不兼容性,从而实现对DataFrame正确地添加分组滚动平均值列,确保计算结果的准确性和数据的完整性。

在数据分析中,对分组数据计算滚动统计量(如滚动平均值)是一项常见的操作。Pandas库提供了强大的groupby()和rolling()方法来支持此类计算。然而,在使用这些方法并将结果赋值回原始DataFrame时,用户可能会遇到TypeError: incompatible index of inserted column with frame index错误或得到不符合预期的计算结果。本文将详细解析这个问题的原因,并提供一个简洁有效的解决方案。

理解问题:分组滚动平均值的索引不兼容性

首先,让我们通过一个示例数据集来重现并理解这个问题。

import pandas as pd
import numpy as np

# 创建示例DataFrame
df = pd.DataFrame({
    'a': np.random.choice(['x', 'y'], 8),
    'b': np.random.choice(['r', 's'], 8),
    'c': np.arange(1, 8 + 1)
})

print("原始DataFrame:")
print(df)

一个可能的输出如下:

原始DataFrame:
   a  b  c
0  y  s  1
1  y  r  2
2  y  s  3
3  y  r  4
4  y  s  5
5  x  r  6
6  y  r  7
7  x  r  8

现在,我们尝试按照列'a'和'b'进行分组,然后计算列'c'的窗口大小为3的滚动平均值,并直接将其赋值给原始DataFrame的新列'ROLLING_MEAN':

# 尝试直接赋值(会导致TypeError)
# df['ROLLING_MEAN'] = df.groupby(['a', 'b'])['c'].rolling(3).mean()

如果直接执行上述代码,Pandas会抛出TypeError: incompatible index of inserted column with frame index。这是因为df.groupby(['a', 'b'])['c'].rolling(3).mean()这个操作的返回值是一个带有多级索引(MultiIndex)的Series。这个多级索引包含了分组键('a'和'b')以及原始DataFrame的索引。例如,单独查看其输出:

intermediate_result = df.groupby(['a', 'b'])['c'].rolling(3).mean()
print("\ngroupby().rolling().mean()的中间结果(带有MultiIndex):")
print(intermediate_result)

一个可能的输出(注意索引结构):

groupby().rolling().mean()的中间结果(带有MultiIndex):
a  b   
x  r  5    NaN
      7    NaN
   s  3    NaN
y  r  1    NaN
      4    NaN
      6    5.0
y  s  0    NaN
      2    NaN
Name: c, dtype: float64

(请注意,示例输出中的索引值和原始DataFrame的索引值可能因为np.random.choice的随机性而有所不同,但关键在于其索引结构是a, b和原始索引的组合。)

由于这个Series的索引与原始DataFrame的单级整数索引不兼容,Pandas无法直接将其作为新列插入。

Okaaaay
Okaaaay

适用于所有人的AI文本和内容生成器

下载

错误的.values使用及其影响

有时,为了规避TypeError,用户可能会尝试在.mean()后面加上.values:

# 尝试使用.values(会避免TypeError,但结果不准确)
df['ROLLING_MEAN_VALUES'] = df.groupby(['a', 'b'])['c'].rolling(3).mean().values
print("\n使用.values后的DataFrame(结果不准确):")
print(df)

虽然.values操作会提取Series中的数值数组,避免了索引不兼容的错误,但它破坏了数据与原始DataFrame行的对应关系。.values只是简单地按顺序提取数值,而没有考虑原始DataFrame的行索引。这意味着计算出的滚动平均值会错误地分配到DataFrame的行中,导致结果完全不准确。

例如,如果我们查看某个特定分组的滚动平均值,会发现其值与该分组的数据完全不匹配。

解决方案:使用 droplevel() 移除多级索引

解决这个问题的关键在于,我们需要将groupby().rolling().mean()返回的Series的多级索引降维(droplevel),使其只保留原始DataFrame的行索引。这样,生成的Series就能与原始DataFrame的索引对齐,从而实现正确的赋值。

droplevel()方法可以从MultiIndex中移除一个或多个级别。在本例中,我们需要移除代表分组键的'a'和'b'级别。

# 正确的解决方案:使用 droplevel()
df['ROLLING_MEAN'] = df.groupby(['a', 'b'])['c'] \
                        .rolling(3).mean() \
                        .droplevel(['a', 'b'])

print("\n使用droplevel()后的DataFrame(结果正确):")
print(df)

一个可能的输出如下:

使用droplevel()后的DataFrame(结果正确):
   a  b  c  ROLLING_MEAN
0  y  s  1           NaN
1  y  r  2           NaN
2  y  s  3           NaN
3  y  r  4           NaN
4  y  s  5      3.000000
5  x  r  6           NaN
6  y  r  7      4.333333
7  x  r  8           NaN

结果验证: 让我们手动验证一个分组的计算。假设在上述输出中,df的索引4对应的行是y, s, 5,并且其ROLLING_MEAN是3.000000。 如果df的原始数据是:

   a  b  c
0  y  s  1
1  y  r  2
2  y  s  3
3  y  r  4
4  y  s  5

对于分组 ('y', 's'),其 c 列的值序列是 1, 3, 5。

  • 索引0 (c=1): NaN (窗口不足3)
  • 索引2 (c=3): NaN (窗口不足3)
  • 索引4 (c=5): (1 + 3 + 5) / 3 = 3.0。 这与输出结果一致。

注意事项

  1. 索引对齐的重要性: Pandas的核心优势之一是其强大的索引对齐功能。在进行复杂的转换和合并操作时,始终要关注Series或DataFrame的索引结构,确保它们能够正确对齐。
  2. rolling() 的 min_periods 参数: 默认情况下,rolling()要求窗口中有足够的非NaN值才能进行计算。例如,rolling(3)表示需要至少3个值才能计算平均值。可以通过设置min_periods参数来改变这一行为,例如rolling(3, min_periods=1)表示只要有1个值就可以计算。
  3. 链式操作的可读性: 当进行多步操作时,使用括号和换行符可以提高代码的可读性,如示例中所示。

总结

在Pandas中对分组数据计算滚动平均值并将其添加回原始DataFrame时,groupby().rolling().mean()操作会产生一个带有MultiIndex的Series,这与原始DataFrame的单级索引不兼容。解决此问题的正确方法是使用.droplevel(['group_key1', 'group_key2'])方法,将MultiIndex降维,使其索引与原始DataFrame的索引对齐。通过这种方式,可以确保计算结果的准确性,并避免常见的TypeError。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

数据分析的方法
数据分析的方法

数据分析的方法有:对比分析法,分组分析法,预测分析法,漏斗分析法,AB测试分析法,象限分析法,公式拆解法,可行域分析法,二八分析法,假设性分析法。php中文网为大家带来了数据分析的相关知识、以及相关文章等内容。

460

2023.07.04

数据分析方法有哪几种
数据分析方法有哪几种

数据分析方法有:1、描述性统计分析;2、探索性数据分析;3、假设检验;4、回归分析;5、聚类分析。本专题为大家提供数据分析方法的相关的文章、下载、课程内容,供大家免费下载体验。

274

2023.08.07

网站建设功能有哪些
网站建设功能有哪些

网站建设功能包括信息发布、内容管理、用户管理、搜索引擎优化、网站安全、数据分析、网站推广、响应式设计、社交媒体整合和电子商务等功能。这些功能可以帮助网站管理员创建一个具有吸引力、可用性和商业价值的网站,实现网站的目标。

722

2023.10.16

数据分析网站推荐
数据分析网站推荐

数据分析网站推荐:1、商业数据分析论坛;2、人大经济论坛-计量经济学与统计区;3、中国统计论坛;4、数据挖掘学习交流论坛;5、数据分析论坛;6、网站数据分析;7、数据分析;8、数据挖掘研究院;9、S-PLUS、R统计论坛。想了解更多数据分析的相关内容,可以阅读本专题下面的文章。

502

2024.03.13

Python 数据分析处理
Python 数据分析处理

本专题聚焦 Python 在数据分析领域的应用,系统讲解 Pandas、NumPy 的数据清洗、处理、分析与统计方法,并结合数据可视化、销售分析、科研数据处理等实战案例,帮助学员掌握使用 Python 高效进行数据分析与决策支持的核心技能。

71

2025.09.08

Python 数据分析与可视化
Python 数据分析与可视化

本专题聚焦 Python 在数据分析与可视化领域的核心应用,系统讲解数据清洗、数据统计、Pandas 数据操作、NumPy 数组处理、Matplotlib 与 Seaborn 可视化技巧等内容。通过实战案例(如销售数据分析、用户行为可视化、趋势图与热力图绘制),帮助学习者掌握 从原始数据到可视化报告的完整分析能力。

55

2025.10.14

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

78

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
R 教程
R 教程

共45课时 | 4.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号