优化Python Pandas中DataFrame填充与重填充的高效实现方案
高效填充Numpy数组至DataFrame的通用优化方案
你的问题核心是行级循环赋值导致大数据量下性能暴跌,再加上y_train维度不固定需要兼容处理。直接用Pandas的向量化操作+维度统一处理就能解决,完全避免循环,同时保证数据对齐和完整性。
一、核心优化步骤
1. 统一y_train的维度
不管y_train是一维(195,)还是多维(195,k),先转成二维数组,避免后续赋值时的索引对齐问题:
y_train = np.asarray(y_train) # 一维数组转成列向量,多维保持原样 if y_train.ndim == 1: y_train = y_train.reshape(-1, 1)
2. 批量生成列名并一次性赋值
直接把Numpy数组批量赋值给DataFrame的新列,这是Pandas效率最高的方式,没有循环开销:
# 按规则生成新列名,前缀可自定义 new_col_names = [f"pred_{i}" for i in range(y_train.shape[1])] # 向量化赋值,一步完成所有列的填充 df[new_col_names] = y_train
3. 高效修改原有列名
修改列名直接用rename的字典映射,或者批量生成新列名,比循环修改快得多:
# 单个/少量列修改 df.rename(columns={"old_col1": "new_col1", "old_col2": "new_col2"}, inplace=True) # 批量修改所有列(比如加前缀) # df.columns = [f"feat_{col}" for col in df.columns]
二、数据完整性保障
必须加校验步骤,避免行数不匹配导致的数据错位:
# 填充前检查行数一致 assert len(df) == y_train.shape[0], "DataFrame和y_train行数不匹配,填充会错位" # 填充后检查无缺失值 assert df[new_col_names].isna().sum().sum() == 0, "新增列存在缺失值,填充失败"
三、为什么原代码慢?
大概率你之前是用df.loc逐行循环赋值,比如这种写法:
# 低效写法示例,别用! for i in range(len(df)): for j in range(y_train.shape[1]): df.loc[i, f"pred_{j}"] = y_train[i, j]
这种行级操作每次都会触发DataFrame的内部更新,行数和列数一多,累计开销会指数级上升。而向量化赋值直接操作底层Numpy数组,一次性完成所有数据写入,效率差几个数量级。
四、完整可运行示例
import pandas as pd import numpy as np # 模拟样本DataFrame df = pd.DataFrame(np.random.rand(195, 3), columns=["col1", "col2", "col3"]) # 修改原有列名 df.rename(columns={"col1": "feature_1", "col2": "feature_2", "col3": "feature_3"}, inplace=True) # 模拟任意形状的y_train(可切换测试) y_train = np.random.rand(195, 24) # (195,24) # y_train = np.random.rand(195, 1) # (195,1) # y_train = np.random.rand(195, 5) # (195,5) # y_train = np.random.rand(195) # 一维(195,) # 统一维度 y_train = np.asarray(y_train) if y_train.ndim == 1: y_train = y_train.reshape(-1, 1) # 生成新列名 new_col_names = [f"pred_{idx}" for idx in range(y_train.shape[1])] # 数据校验 assert len(df) == y_train.shape[0], "行数不匹配,无法填充" # 批量填充 df[new_col_names] = y_train # 验证无缺失 assert df[new_col_names].isna().any().any() == False, "填充失败,存在缺失值" # 查看结果 print(df.head())
内容的提问来源于stack exchange,提问作者Jaffer Wilson
相关产品推荐
相关产品推荐

