如何在DataFrame中匹配并移除金额互为相反数的订单与退款记录
解决DataFrame中订单与退款记录的匹配移除问题
原始数据
首先定义原始数据并生成DataFrame:
import pandas as pd test = {"number": ['1555','1666','1777', '1888', '1999'], "order_amount": ['100.00','200.00','-200.00', '300.00', '-150.00'], "number_of_refund": ['','','1666', '', '1888'] } df = pd.DataFrame(test)
生成的初始DataFrame如下:
number order_amount number_of_refund 0 1555 100.00 1 1666 200.00 2 1777 -200.00 1666 3 1888 300.00 4 1999 -150.00 1888
需求说明
需要移除同时满足以下条件的订单及退款记录:
number_of_refund列的值在当前DataFrame的number列中存在匹配项- 匹配到的
number对应的order_amount与该退款记录的order_amount互为相反数(例如1666的订单金额200和退款记录的-200,两行均需移除)
最终期望结果:
number order_amount number_of_refund 0 1555 100.00 3 1888 300.00 4 1999 -150.00 1888
实现方案
步骤1:转换金额列类型
原始金额为字符串格式,需转为数值型才能进行运算:
df['order_amount'] = df['order_amount'].astype(float)
步骤2:构建订单金额映射
创建一个字典,存储非退款记录(number_of_refund为空)的订单号与对应金额的映射:
order_map = df[df['number_of_refund'] == ''].set_index('number')['order_amount'].to_dict()
步骤3:定位需要移除的行
- 找出符合条件的退款记录索引:
refund_indices = df[ df['number_of_refund'].isin(order_map.keys()) & (df['order_amount'] == -df['number_of_refund'].map(order_map)) ].index
这里通过map方法直接将number_of_refund映射到对应订单金额,再判断退款金额是否为其相反数。
- 找出这些退款记录对应的原始订单索引:
order_indices = df[df['number'].isin(df.loc[refund_indices, 'number_of_refund'])].index
- 合并索引并过滤DataFrame:
drop_indices = refund_indices.union(order_indices) result_df = df.drop(drop_indices).reset_index(drop=True)
关于金额互为相反数的检查逻辑
核心是通过映射匹配+数值对比实现:
- 先建立有效订单的金额映射,避免重复查找
- 对每条退款记录,用
number_of_refund匹配到对应订单金额,直接判断退款金额 == -订单金额 - 利用Pandas的布尔索引快速筛选符合条件的行
内容的提问来源于stack exchange,提问作者Kirilas
相关产品推荐
相关产品推荐

