
本文介绍如何利用 pandas 将字典中定义的转换因子与 dataframe 中对应项的数值进行批量乘法运算,并为每一行计算其可转换项中的最小值,最终作为新列添加到原表中。
本文介绍如何利用 pandas 将字典中定义的转换因子与 dataframe 中对应项的数值进行批量乘法运算,并为每一行计算其可转换项中的最小值,最终作为新列添加到原表中。
在实际数据分析中,常需根据外部映射关系(如单位换算、价格系数、权重因子等)对数据进行动态转换,并进一步聚合(如取最小值、最大值)。本教程以一个典型场景为例:给定一个转换因子字典 data 和一个主数据表 df,目标是为 df 中每个 Item 计算其“可被转换项”在 Col1 值经系数缩放后的最小值,并将结果存入新列 Minc_Col1。
✅ 核心思路解析
- 对齐映射:字典 data 的行索引(如 ‘Item5’, ‘Item6’)需与 df 中 Col0 的值匹配,从而获取对应 Col1 数值作为基础值;
- 广播乘法:利用 DataFrame.mul(…, axis=0) 沿行方向将 data 的每行乘以对应 Col1 值,生成转换后矩阵;
- 按列求最小:因 data 的列代表目标项(如 ‘Item1’, ‘Item2’),故对乘法结果按列取 min(),即得每个目标项能获得的最小转换值;
- 安全对齐:未在 data.index 中出现的 df[‘Col0’] 项(如 ‘Item3’, ‘Item5’, ‘Item6’)会导致部分乘积为 NaN,min() 自动跳过 NaN;若整列全 NaN,则结果为 NaN,符合预期。
? 完整实现代码
import pandas as pd
# 转换因子字典(行=源项,列=目标项)
data = {
'Item1': {'Item5': 10, 'Item6': 100, 'Item4': 1},
'Item2': {'Item5': 10, 'Item6': 100, 'Item4': 1},
'Item4': {'Item5': 10, 'Item6': 100, 'Item9': 1}
}
data = pd.DataFrame(data).T # 确保列为目标项,行为源项(与后续 map 对齐)
# 主数据表
df = pd.DataFrame({
'Col0': ['Item1', 'Item2', 'Item3', 'Item4', 'Item5', 'Item6'],
'Col1': [180, 250, 150, 205, 22, 2],
'Col2': [190, 150, 150, 200, 18, 2.5]
})
# 步骤1:以 Col0 为索引,便于 map 查找
result = df.set_index('Col0')
# 步骤2:用 data.index 映射 result['Col1'] 获取各源项的基准值(如 Item5→22)
factors = data.index.map(result['Col1'])
# 步骤3:广播乘法 + 按列取最小 → 得到每个目标项(Item1/Item2/Item4)的 min converted value
min_values = data.mul(factors, axis=0).min()
# 步骤4:assign 新列,重置索引,重命名列
result = (
result.assign(Minc_Col1=min_values)
.reset_index()
.rename(columns={'Col0': 'Item', 'Col1': 'Price1', 'Col2': 'Price2'})
)
print(result)
输出结果:
Item Price1 Price2 Minc_Col1 0 Item1 180 190.0 200.0 1 Item2 250 150.0 200.0 2 Item3 150 150.0 NaN 3 Item4 205 200.0 200.0 4 Item5 22 18.0 NaN 5 Item6 2 2.5 NaN
⚠️ 注意事项与常见问题
- 字典结构关键:data 必须为 pd.DataFrame,且其 行索引(index)必须与 df[‘Col0’] 中的源项完全一致(如 ‘Item5’, ‘Item6’),否则 map 返回 NaN,导致整列乘积失效;
- NaN 处理逻辑:min() 默认忽略 NaN;若某目标项(如 ‘Item1’)所有可转换源项均无对应 Col1 值(全 NaN),则结果为 NaN;
- 列名对齐:data.columns 应覆盖所有需计算 Minc_Col1 的目标项(如 ‘Item1’, ‘Item2’, ‘Item4’),缺失列不会出现在结果中;
- 性能提示:该方法基于向量化运算,适用于万级以内数据;超大规模时可考虑 numba 加速或分块处理。
? 进阶扩展(可选)
如需同时返回最小值来源项(例如知道 200 是由 ‘Item6’ 贡献),可使用:
m = data.mul(factors, axis=0)
min_series = m.min()
source_item = m.idxmin() # 返回每列最小值所在行索引(即源项名)
# 合并到结果
result = result.assign(
Minc_Col1=min_series,
Source_Item=source_item
)
此方案兼顾可读性、健壮性与扩展性,是 Pandas 高效实现“映射-转换-聚合”类任务的标准范式。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/jiquanzatan/125587.html