如何用Pandas移除含valueRemaining为0的oldVoucherId所有行?
解决方案
步骤说明
要实现需求,需完成两个核心操作:
- 剔除所有包含
valueRemaining=0的oldVoucherId对应的全部行 - 对保留的每个
oldVoucherId,提取最新的有效余额记录并统一格式
完整代码实现
import pandas as pd # 测试数据 data = {'oldVoucherId': ['1', '1', '1', '2', '2', '2', '5', '5', '5', '3', '3', '8', '9'], 'valuePurchased': ['60','','','70','','','50','','','40','','50','70'], 'valueRemaining': ['','50','40','','60','0','','45','0','','0','','']} df = pd.DataFrame(data) # 1. 转换字符串列为数值类型,空字符串转为NaN df['valuePurchased'] = pd.to_numeric(df['valuePurchased'], errors='coerce') df['valueRemaining'] = pd.to_numeric(df['valueRemaining'], errors='coerce') # 2. 找出所有存在valueRemaining=0的oldVoucherId exclude_ids = df[df['valueRemaining'] == 0]['oldVoucherId'].unique() # 3. 筛选保留未被排除的id对应的行 filtered_df = df[~df['oldVoucherId'].isin(exclude_ids)] # 4. 按id分组取最后一行(最新余额记录) result_df = filtered_df.groupby('oldVoucherId', as_index=False).last() # 5. 统一格式:未使用的代金券(无余额记录)将购买额转为余额,清空购买额列 mask = result_df['valueRemaining'].isna() result_df.loc[mask, 'valueRemaining'] = result_df.loc[mask, 'valuePurchased'] result_df.loc[mask, 'valuePurchased'] = pd.NA # 6. 转换回原数据的空字符串格式(可选,若不需要数值类型可执行) result_df = result_df.fillna('') print(result_df)
代码解释
- 类型转换:将字符串列转为数值类型,空字符串转为
NaN,便于后续数值判断和计算 - 排除id筛选:通过布尔索引找出所有出现过
valueRemaining=0的代金券ID,这些ID的所有行都需要剔除 - 分组取最新记录:每个代金券的余额记录按时间顺序更新,最后一行即为最新的余额状态
- 格式统一:从未使用的代金券(无余额记录)将购买金额填充到余额列,同时清空购买金额列,与已使用代金券的格式保持一致
运行后输出结果与预期完全匹配:
| oldVoucherId | valuePurchased | valueRemaining |
|---|---|---|
| 1 | 40 | |
| 8 | 50 | |
| 9 | 70 |
内容的提问来源于stack exchange,提问作者robster
相关产品推荐
相关产品推荐

