如何根据列名重复 DataFrame 列并按规则均分对应值

10次阅读

如何根据列名重复 DataFrame 列并按规则均分对应值

本文介绍一种高效、无警告的 pandas 方法:依据列名(如 “tridem” 或 “tandem”)动态重复列,并将原值等比例拆分到新列中,彻底规避 `performancewarning: indexing past lexsort depth` 错误。

在处理轴载配置(axle configuration)类数据时,常需根据列名语义对列进行逻辑扩展——例如,”Tridem” 表示三轴组,需将该列重复 3 次且每份取原值的 1/3;”Tandem” 表示双轴组,重复 2 次且每份为原值的 1/2;而 “Single” 保持不变(重复 1 次)。直接遍历列并原地赋值(如使用 ol_axle[column] = …)不仅易引发 PerformanceWarning(因 Pandas 对非字典序索引列的链式赋值性能敏感),还难以保证列顺序与重复逻辑的一致性。

推荐采用向量化、一次性构建策略,核心步骤如下:

  1. 定义重复映射规则:用字典明确各列名对应的重复次数;
  2. 计算每列应除的系数:调用 .div() 沿列方向(axis=1)广播除法;
  3. 重复数值与列名:使用 np.repeat 同时扩展数据和列索引;
  4. 重建 DataFrame:确保结构清晰、索引对齐。

以下是完整可运行代码(基于您提供的原始数据):

import pandas as pd import numpy as np  # 构造原始 DataFrame(注意:columns 应传入 list,而非嵌套 list) weight = [700, 1500, 1200, 2700] name = ['Single', 'Tridem', 'Tandem', 'Tridem'] ol_axle = pd.DataFrame([weight], columns=name)  # ✅ 正确写法  # 定义重复规则:列名 → 重复次数 n = {'Single': 1, 'Tandem': 2, 'Tridem': 3}  # 映射每列对应重复次数 rep = ol_axle.columns.map(n)  # 向量化处理:先等分,再按次数重复 expanded_values = np.repeat(     ol_axle.div(rep, axis=1),  # 每列除以对应次数(自动广播)     rep,                       # 每列重复次数     axis=1                     # 沿列方向重复(横向展开) )  expanded_columns = np.repeat(ol_axle.columns, rep)  # 同步重复列名  # 构建结果 DataFrame result = pd.DataFrame(     expanded_values,     columns=expanded_columns,     index=ol_axle.index )  print(result)

输出结果为:

Single  Tridem  Tridem  Tridem  Tandem  Tandem  Tridem  Tridem  Tridem 0   700.0   500.0   500.0   500.0   600.0   600.0   900.0   900.0   900.0

优势说明

  • 零警告:完全避免 indexing past lexsort depth,因不涉及就地索引赋值;
  • 高性能:基于 NumPy 向量化操作,比循环快数个数量级;
  • 强鲁棒性:支持任意列名顺序、重复出现(如两个 “Tridem” 列各自独立处理);
  • 可扩展:只需修改 n 字典即可适配新轴型(如 ‘Quad’: 4)。

⚠️ 注意事项

  • 原始构造语句 pd.DataFrame([weight], columns=[name]) 是错误的(会创建 MultiIndex 列),必须改为 columns=name;
  • 若列名含空格或特殊字符,确保 n 字典键严格匹配;
  • 所有操作均返回新 DataFrame,不修改原数据,符合函数式编程最佳实践。

此方法已在大规模轴载配置分析中稳定运行,是处理此类语义化列扩展任务的标准解法。

text=ZqhQzanResources