Pandas中基于分组均值填充缺失值的专业指南

霞舞
发布: 2025-11-06 13:47:36
原创
570人浏览过

Pandas中基于分组均值填充缺失值的专业指南

本文详细介绍了在pandas dataframe中,如何高效且准确地根据另一列的分组均值来填充目标列中的缺失值(nan)。通过使用`groupby()`结合`transform('mean')`方法,可以生成与原始dataframe索引对齐的组均值序列,进而利用`fillna()`函数实现批量填充,避免了`inplace`参数误用导致的常见问题

数据清洗和预处理过程中,处理缺失值是一个常见且重要的步骤。当缺失值的填充逻辑依赖于数据中特定分组的统计量时,例如根据某个分类列的均值来填充数值列的缺失值,Pandas提供了强大而灵活的工具来完成这项任务。本教程将深入探讨如何利用groupby()和transform()方法,结合fillna()函数,实现基于分组均值的高效缺失值填充。

理解问题与常见误区

假设我们有一个DataFrame,其中一列包含缺失值,而我们需要根据另一列(如类别列)的不同分组来计算各自的均值,并用这些均值来填充对应分组的缺失值。

例如,原始问题中提及的场景:

import pandas as pd

# 假设df是原始DataFrame,其中'InternetService'是分组列,'Bandwidth_GB_Year'是需要填充的列
# mean_values = df.groupby("InternetService")["Bandwidth_GB_Year"].mean().round(3)
# print(mean_values)
登录后复制

如果直接尝试使用df["Bandwidth_GB_Year"].fillna(mean_values, inplace=True),可能会遇到问题。fillna()函数在接收一个Series作为参数时,会尝试根据索引进行匹配。虽然mean_values包含了分组均值,但它的索引是InternetService的唯一值,而不是原始DataFrame的行索引。因此,直接传入mean_values并期望它能智能地根据InternetService列进行匹配填充,是无法实现的。

更重要的是,当使用df["Bandwidth_GB_Year"] = df["Bandwidth_GB_Year"].fillna(mean_values, inplace = True)这种形式时,inplace=True会使得fillna()函数在原始Series上直接进行修改,并返回None。这意味着赋值操作df["Bandwidth_GB_Year"] = None,从而导致整个列被替换为None。这是使用inplace=True时一个非常常见的误区,尤其是在将其结果赋值给变量时。

使用 groupby().transform('mean') 进行高效填充

解决上述问题的关键在于生成一个与原始DataFrame索引对齐的Series,其中每个元素都是其对应分组的均值。groupby()方法结合transform()函数正是为此而设计。

transform()方法在groupby对象上应用一个函数(如mean),并返回一个与原始DataFrame或Series具有相同索引和长度的Series。对于每个原始行,transform()会根据其所属的分组计算并返回该分组的聚合结果。

示例代码

让我们通过一个简化的例子来演示这个过程:

import pandas as pd
import numpy as np

# 创建一个示例DataFrame
df = pd.DataFrame({
    'col1': [1, 2, 1, 2, 1, 1, 2, 3, 3, 3],
    'col2': [5, 4, np.nan, 3, np.nan, 7, 9, 1, np.nan, 2]
})

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

# 根据 'col1' 列分组,并用 'col2' 列的均值填充缺失值
# 1. 使用 groupby().transform('mean') 生成一个与df['col2']索引对齐的均值Series
group_means_aligned = df.groupby('col1')['col2'].transform('mean')

print("\n根据 'col1' 分组的 'col2' 均值(已对齐原始索引):")
print(group_means_aligned)

# 2. 使用 fillna() 方法填充缺失值
df['col2'] = df['col2'].fillna(group_means_aligned)

print("\n填充缺失值后的 DataFrame:")
print(df)
登录后复制

代码解析:

硅基智能
硅基智能

基于Web3.0的元宇宙,去中心化的互联网,高质量、沉浸式元宇宙直播平台,用数字化重新定义直播

硅基智能 62
查看详情 硅基智能
  1. df.groupby('col1')['col2']: 这部分代码将DataFrame按'col1'列进行分组,并选择'col2'列作为我们进行操作的目标。
  2. .transform('mean'): 对每个分组中的'col2'列计算均值。关键在于transform会将这个均值“广播”回原始的行索引。例如,对于col1为1的所有行,transform('mean')会返回col1为1的组的均值;对于col1为2的所有行,则返回col1为2的组的均值,依此类推。
  3. df['col2'].fillna(group_means_aligned): fillna()函数接收group_means_aligned作为参数。由于group_means_aligned的索引与df['col2']的索引完全匹配,fillna()能够准确地找到df['col2']中的NaN值,并用group_means_aligned中对应索引位置的值进行填充。

输出结果:

原始 DataFrame:
   col1  col2
0     1   5.0
1     2   4.0
2     1   NaN
3     2   3.0
4     1   NaN
5     1   7.0
6     2   9.0
7     3   1.0
8     3   NaN
9     3   2.0

根据 'col1' 分组的 'col2' 均值(已对齐原始索引):
0    6.0
1    5.333333
2    6.0
3    5.333333
4    6.0
5    6.0
6    5.333333
7    1.5
8    1.5
9    1.5
Name: col2, dtype: float64

填充缺失值后的 DataFrame:
   col1       col2
0     1   5.000000
1     2   4.000000
2     1   6.000000
3     2   3.000000
4     1   6.000000
5     1   7.000000
6     2   9.000000
7     3   1.000000
8     3   1.500000
9     3   2.000000
登录后复制

从结果可以看出,col1为1的组(原始值5, NaN, NaN, 7)均值为(5+7)/2 = 6.0,缺失值被填充为6.0。col1为2的组(原始值4, 3, 9)均值为(4+3+9)/3 = 5.333,缺失值被填充为5.333。col1为3的组(原始值1, NaN, 2)均值为(1+2)/2 = 1.5,缺失值被填充为1.5。

注意事项

  1. inplace 参数的正确使用:

    • 当使用df[column] = ...进行赋值操作时,切勿在右侧的函数中包含inplace=True。inplace=True会修改原始对象并返回None,导致赋值为None。
    • 如果希望直接修改DataFrame而不进行赋值,可以单独调用df['col2'].fillna(group_means_aligned, inplace=True)。但为了代码的清晰性和避免副作用,通常推荐df['col2'] = df['col2'].fillna(group_means_aligned)这种显式赋值的方式。
  2. 数据类型:

    • 如果原始列是整数类型(如int64),并且包含NaN(在Pandas中,NaN是浮点类型),那么该列的数据类型会自动提升为浮点型(如float64)。填充均值后,列仍将保持浮点型,因为均值通常不是整数。
    • 如果需要将填充后的列转换回整数(在确认没有小数部分或可以接受截断的情况下),可以使用df['col2'] = df['col2'].astype(int),但这会丢失小数信息。如果存在小数,可以使用df['col2'] = df['col2'].round().astype(int)进行四舍五入。
  3. 多列填充:

    • 如果需要根据相同的分组逻辑填充多列,可以对多列应用transform('mean')。
    • 例如:df[['col2', 'col3']] = df.groupby('col1')[['col2', 'col3']].transform('mean')。
  4. 其他聚合函数

    • 除了'mean',transform()还可以与'median'、'sum'、'max'、'min'等其他聚合函数配合使用,以满足不同的填充需求。

总结

通过groupby().transform('mean')结合fillna(),我们能够优雅且高效地解决Pandas DataFrame中基于分组均值填充缺失值的需求。这种方法不仅避免了常见的inplace参数误用,而且生成的代码简洁、易读,是数据预处理中的一项重要技能。理解transform()的工作原理,即它如何将分组聚合结果“广播”回原始DataFrame的索引,是掌握此技巧的关键。

以上就是Pandas中基于分组均值填充缺失值的专业指南的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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