Pandas:如何基于对称DataFrame为另一DataFrame的所有值应用条件
解决DataFrame按条件替换值的问题(对称与非对称场景)
一、对称DataFrame场景(行列完全匹配)
你的原代码问题在于applymap的lambda参数是单个元素,无法直接关联qty_pct的对应位置。推荐用pandas向量化操作,效率更高且逻辑清晰:
方法1:布尔索引直接赋值
这是最简洁高效的实现方式,利用布尔掩码定位需要替换的位置:
import numpy as np import pandas as pd d = {'qty_pct': pd.DataFrame({ '2020': [200, 0.5, 0.4], '2021': [0.9, 0.5, 500], '2022': [0.9, 300, 0.4]}), 'price': pd.DataFrame({ '2020': [-6, -2, -9], '2021': [ 2, 3, 4], '2022': [ 4, 6, 8]})} # 生成布尔掩码:标记qty_pct >=1 的位置 mask = d['qty_pct'] >= 1 # 对price对应位置赋值为0 d['price'][mask] = 0 print(d['price'])
输出结果符合预期:
2020 2021 2022 0 0 2 4 1 -2 3 0 2 -9 4 8
方法2:使用where方法
一行代码实现需求,逻辑与需求完全匹配:当qty_pct <1时保留price原值,否则替换为0:
d['price'] = d['price'].where(d['qty_pct'] < 1, 0)
二、非对称DataFrame场景(行列不完全匹配)
若两个DataFrame的行/列标签不完全一致,需先对齐行列再操作,分两种处理逻辑:
场景1:对齐所有行列,缺失位置默认不替换
先通过align方法统一两个DataFrame的行列,缺失位置填充0(不影响>=1的判断),再进行替换:
# 构造非对称示例:qty_pct只有2行2列,price有3行3列 d_asym = { 'qty_pct': pd.DataFrame({ '2020': [200, 0.5], '2021': [0.9, 0.5]}), 'price': pd.DataFrame({ '2020': [-6, -2, -9], '2021': [ 2, 3, 4], '2022': [ 4, 6, 8]}) } # 对齐行列,缺失位置填充0 qty_aligned, price_aligned = d_asym['qty_pct'].align(d_asym['price'], fill_value=0) # 生成掩码并替换 mask = qty_aligned >= 1 d_asym['price'] = price_aligned.where(~mask, 0) print(d_asym['price'])
输出:
2020 2021 2022 0 0 2 4 1 -2 3 6 2 -9 4 8
场景2:仅在共同行列区域替换
如果只希望修改两个DataFrame行和列都匹配的位置,其他区域保留price原值:
# 获取共同的行和列标签 common_rows = d_asym['qty_pct'].index.intersection(d_asym['price'].index) common_cols = d_asym['qty_pct'].columns.intersection(d_asym['price'].columns) # 仅对共同区域生成掩码并替换 mask = d_asym['qty_pct'].loc[common_rows, common_cols] >= 1 d_asym['price'].loc[common_rows, common_cols] = d_asym['price'].loc[common_rows, common_cols].where(~mask, 0)
内容的提问来源于stack exchange,提问作者Phil P.
相关产品推荐
相关产品推荐

