如何在Pandas中对不同索引的多数据集列执行关联运算?
问题分析
你的核心问题在于直接通过loc筛选后做元素级乘法时,筛选后的Series行顺序和volume的id顺序不匹配,导致乘积结果和id的对应关系完全错乱,后续merge自然会出现错位、NaN和多余行。
解决方案
要实现按id(以及room_name,因为volume是从floor基于square的room_name过滤得到)对齐的乘积计算,推荐分两步关联所需列,再进行运算:
方法1:使用merge逐步关联(直观易维护)
# 第一步:关联square,获取对应room_name的square值(因为volume的行是floor中保留square有值的room_name,所以left join不会有NaN) volume = volume.merge(square[["id", "room_name", "square"]], on=["id", "room_name"], how="left") # 第二步:关联matc,获取对应id的width值 volume = volume.merge(matc[["id", "width"]], on="id", how="left") # 计算目标列,自动按行对齐 volume["target_col"] = volume["coefLoosening"] * volume["width"] * volume["square"] # 可选:如果不需要保留中间关联的列,可以删除 volume = volume.drop(columns=["square", "width"])
方法2:使用映射(更高效,适合大数据集)
如果数据集较大,merge的性能不如映射操作,可以用索引映射来实现:
# 构建id到width的映射(matc中id唯一) width_mapper = matc.set_index("id")["width"] # 构建(id, room_name)到square值的映射(square中每个(id, room_name)唯一) square_mapper = square.set_index(["id", "room_name"])["square"] # 通过映射获取对应值并计算 volume["target_col"] = ( volume["coefLoosening"] * volume["id"].map(width_mapper) * volume.apply(lambda row: square_mapper.get((row["id"], row["room_name"])), axis=1) )
原代码错误原因
matc.loc[matc["id"].isin(volume["id"])]['width']筛选出的行顺序和volume的id顺序完全无关,直接相乘会导致值对应错误;- 构造临时DataFrame时,
id来自matc筛选后的结果,tempCoef是错位的乘积,两者的对应关系本身就是错的,merge后自然出现大量NaN和错位。
内容的提问来源于stack exchange,提问作者el_bulm
相关产品推荐
相关产品推荐

