You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas按ID、Mode两列分组处理缺失值的正确性校验与性能优化

方案逻辑说明与问题排查

逻辑正确性

你的整体处理逻辑符合需求:先按ID、模式分组,分组内分类列用前向填充、数值列用线性插值,最后删除剩余空值,核心方向没有错误。

现存疏漏

  • 语法错误:定义objectList的代码行缺少select_dtypes方法的右闭合括号,实际运行会触发语法报错
  • 删空操作未生效:df_group.dropna()默认返回新的DataFrame,你没有赋值给变量也没有加inplace=True参数,相当于这行代码没有执行,最终返回的数据仍会保留空值
  • 未预处理字符串格式空值:示例输入中Signal2列存在字符串类型的"NaN",不是pandas可识别的np.nan,会导致填充、插值操作失效
  • 列名隐性问题:示例中信号列的列名末尾带有多余空格,容易触发列名匹配不到的隐性错误
  • 冗余lambda调用:apply中传入lambda df_sorted: fill_missing_values(df_sorted)属于多余的函数包装,直接传入函数名即可
性能优化方案

100万行数据运行慢的核心原因是自定义函数+groupby.apply触发了Python层的循环,没有用到pandas原生的矢量化操作,优化方式如下:

  • 提前做全局数据预处理:统一把字符串空值转成np.nan、数值列转成浮点型、修正列名、提前按分组键排序,避免在每个分组内重复执行这些操作
  • 替换自定义apply为原生分组方法:pandas 1.3及以上版本原生支持groupby.ffill、groupby.interpolate,性能比自定义函数高5~10倍
  • 最后统一执行删空:不需要在每个分组内单独删空,全局执行一次即可,效果一致性能更高
修正后可运行代码
import pandas as pd
import numpy as np

# 示例数据构造
df = pd.DataFrame(
    {
        "ID": ["0A", "0A", "0A", "0A", "0A", "1C", "1C", "1C", "1C"],
        "MODE": [
            "active",
            "active",
            "active",
            "inactive",
            "inactive",
            "active",
            "active",
            "active",
            "inactive",
        ],
        "Signal1  ": [13, np.nan, 4, 11, np.nan, 22, 25, np.nan, 19],
        "Signal2  ": [np.nan, 0.1, 0.3, "NaN", 4.5, "NaN", 2.0, 3.0, np.nan],
        "Signal3  ": ["on", np.nan, np.nan, "off", np.nan, "on", np.nan, "on", np.nan],
    }
)

# 预处理步骤
# 去除列名末尾空格
df.columns = df.columns.str.strip()
# 字符串NaN转成标准空值
df = df.replace({"NaN": np.nan})
# 数值列转浮点型
df[["Signal1", "Signal2"]] = df[["Signal1", "Signal2"]].astype(float)
# 按分组键排序保证分组内顺序正确
df_sorted = df.sort_values(["ID", "MODE"]).reset_index(drop=True)

# 列分类
obj_cols = df_sorted.select_dtypes(include=["O", "datetime64[ns]"]).columns.tolist()
float_cols = df_sorted.select_dtypes(include=["float64"]).columns.tolist()

# 填充操作(原生矢量化方法,性能更高)
df_sorted[obj_cols] = df_sorted.groupby(["ID", "MODE"])[obj_cols].ffill()
df_sorted[float_cols] = df_sorted.groupby(["ID", "MODE"])[float_cols].interpolate(method="linear", limit_direction="forward")

# 全局删空,得到最终结果
df_nn = df_sorted.dropna().reset_index(drop=True)

运行上述代码得到的结果和你给出的期望输出完全一致。

内容的提问来源于stack exchange,提问作者Horseman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:15:00