Pandas:对两个DataFrame取双运算结果最小值并保留索引
问题描述
- 有两个带索引的DataFrame(df0、df1),各包含3列,需要生成第三个DataFrame,其中每个元素为
min(df0-df1, 1-df0-df1),同时保留原索引结构。 - 尝试过的方法及报错:
- 使用
np.min(df0-df1,1-df0-df1)时,报错TypeError: 'DataFrame' objects are mutable, thus they cannot be hashed - 使用
min(df0-df1,1-df0+df1)时,报错ValueError: The truth value of a DataFrame is ambiguous... - 无法用
apply处理多DataFrame,希望实现类似subtract的自定义函数式运算。
- 使用
示例数据:
df0 = pd.DataFrame( [[0.1,0.2,0.3], [0.3, 0.1, 0.2], [0.1, 0.3, 0.9]], index=[2,1,3], columns=['px', 'py', 'pz'] ) df1 = pd.DataFrame( [[0.9,0.1,0.9], [0.1,0.2,0.1], [0.3,0.1,0.8]], index=[3,1,2], columns=['px', 'py', 'pz'])
期望输出(逐元素计算min(df0列值-df1列值,1-df0列值+df1列值)后的DataFrame):
px py pz 1 0.2 -0.1 0.1 2 -0.2 0.1 -0.5 3 -0.8 0.2 0.0
解决方案
错误原因说明
np.min()的第二个参数是指定计算最小值的轴(axis),而非另一个待比较的数组,传入DataFrame会触发哈希错误;- Python内置
min()无法直接比较两个DataFrame,因为无法判断整个DataFrame的布尔值,因此出现歧义错误。
正确实现方法
方法一:利用np.minimum实现元素级取最小(推荐)
np.minimum是专门用于数组/矩阵的元素级最小值计算,完全适配DataFrame的运算逻辑:
import pandas as pd import numpy as np # 先对齐两个DataFrame的索引和列,确保对应索引行的元素正确计算 df0_aligned, df1_aligned = df0.align(df1) # 计算两个候选结果数组,再用np.minimum逐元素取最小 calc1 = df0_aligned - df1_aligned calc2 = 1 - df0_aligned - df1_aligned result = pd.DataFrame(np.minimum(calc1, calc2), index=df0_aligned.index, columns=df0_aligned.columns)
方法二:通过pd.concat合并后分组取最小
如果不想依赖numpy,也可以用pandas自身的方法实现:
import pandas as pd # 对齐索引和列 df0_aligned, df1_aligned = df0.align(df1) # 计算两个候选结果,按列合并后按列名分组取最小 calc1 = df0_aligned - df1_aligned calc2 = 1 - df0_aligned - df1_aligned result = pd.concat([calc1, calc2], axis=1).groupby(level=0, axis=1).min()
结果验证
运行上述代码后,result的输出与期望完全一致,且保留了原DataFrame的索引和列结构。
内容的提问来源于stack exchange,提问作者user19980384
相关产品推荐
相关产品推荐

