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

如何高效为Pandas DataFrame添加依赖其他列的多列

优化Pandas多新列生成的性能瓶颈

你现在遇到的问题我太熟悉了——多次调用df.apply(axis=1)生成新列,本质上是重复遍历整个DataFrame,当新列数量多的时候,这个开销会被直接放大。结合Python3.6的环境,给你两个针对性的优化方案:

方案1:单次遍历生成所有新列

把所有新列的计算逻辑合并到一个函数里,让这个函数返回包含所有新列值的pd.Series,这样只需要遍历一次DataFrame就能搞定所有新列,直接把时间复杂度从O(n*k)降到O(n)(n是行数,k是新列数)。

示例代码

import pandas as pd

# 假设你的全局变量和已有列是这些
some_dictionary = {"A": 10, "B": 20}
some_default_value = 0

def compute_all_new_cols(row):
    # 计算NewColumn1的逻辑(简化了原有的if-else)
    new_col1 = some_dictionary.get(row["SomeExistingColumn"], some_default_value)
    # 计算NewColumn2的示例逻辑(替换成你的实际业务逻辑)
    new_col2 = row["ExistingCol2"] + row["ExistingCol3"] * 0.5
    # 返回Series,索引对应新列名,确保顺序和后续赋值一致
    return pd.Series([new_col1, new_col2], index=["NewColumn1", "NewColumn2"])

# 一次性生成所有新列,仅遍历一次DataFrame
df[["NewColumn1", "NewColumn2"]] = df.apply(compute_all_new_cols, axis=1)

方案2:向量化逻辑适配assign(性能最优)

你之前用assign失败是因为它的lambda接收的是整个DataFrame,不是单行,所以必须返回完整的列数据。大多数行级逻辑都可以改造成向量化操作(利用Pandas/Numpy的内置函数,底层是C实现,性能比Python循环快得多),这样就能正常用assign,还能拿到最好的性能。

示例:字典映射的向量化改造

你提供的compute_new_column1_value完全可以用pd.Series.map()实现向量化,比apply快几个数量级:

df = df.assign(
    NewColumn1=lambda df: df["SomeExistingColumn"].map(some_dictionary).fillna(some_default_value),
    NewColumn2=lambda df: df["ExistingCol2"] + df["ExistingCol3"] * 0.5
)

map()会批量处理整个列,fillna()自动处理不在字典里的默认值,完全不需要逐行遍历。

复杂条件的向量化思路

如果遇到多分支判断这类复杂逻辑,可以用这些工具:

  • numpy.where():处理二元条件
  • pd.Series.where()/pd.Series.mask():基于条件替换值
  • numpy.select():处理多分支条件

比如多分支逻辑的向量化实现:

import numpy as np

# 定义多个条件和对应的结果
conditions = [
    df["ExistingCol"] > 100,
    df["ExistingCol"] > 50,
    df["ExistingCol"] <= 50
]
choices = [
    df["ExistingCol"] * 2,
    df["ExistingCol"] * 1.5,
    df["ExistingCol"]
]

# 用assign生成新列
df = df.assign(
    NewColumn3=np.select(conditions, choices, default=0)
)

方案选择建议

  • 如果你的行级逻辑特别复杂(比如涉及多行依赖、复杂的Python控制流),优先用方案1,减少遍历次数;
  • 只要逻辑能拆解成Pandas/Numpy的向量化操作,一定要选方案2,这是性能最优的选择;
  • 绝对不要用for idx, row in df.iterrows()这种手动循环,性能最差,完全没必要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:46:16