如何从Pandas DataFrame中移除连续的等值异号数对
从Pandas DataFrame中移除数值相等、符号相反的连续数对
测试场景
首先构造示例测试数据:
import pandas as pd incremental_changes = [2, -2, 2, 1, 4, 5, -5, 7, -6, 6] df = pd.DataFrame({ 'idx': range(len(incremental_changes)), 'incremental_changes': incremental_changes })
生成的原始DataFrame内容如下:
| idx | incremental_changes |
|---|---|
| 0 | 2 |
| 1 | -2 |
| 2 | 2 |
| 3 | 1 |
| 4 | 4 |
| 5 | 5 |
| 6 | -5 |
| 7 | 7 |
| 8 | -6 |
| 9 | 6 |
处理后期望得到的结果:
| idx | incremental_changes |
|---|---|
| 0 | 2 |
| 3 | 1 |
| 4 | 4 |
| 7 | 7 |
注:结果中保留的首个2对应原索引0或2均可,无强制要求。
实现方案
这类相邻元素成对抵消的逻辑最适合用栈结构实现,时间复杂度O(n),逻辑清晰易维护:
- 遍历序列时,栈中存储当前已遍历、未被抵消的行记录(原索引+对应增量值)
- 每遍历到一个新值,检查栈是否非空、栈顶存储的值是否和当前值互为相反数
- 如果满足相反数条件,说明这两个值是需要移除的连续数对,直接弹出栈顶元素即可
- 如果不满足条件,将当前行记录压入栈
- 遍历完成后,栈中剩余的记录就是需要保留的内容,直接构造为新的DataFrame即可
对应实现代码:
stack = [] for idx, val in df['incremental_changes'].items(): if stack and stack[-1][1] == -val: # 和栈顶值抵消,弹出栈顶 stack.pop() else: # 无法抵消,压入栈 stack.append((idx, val)) # 生成结果DataFrame result_df = pd.DataFrame(stack, columns=['idx', 'incremental_changes'])
运行上述代码得到的结果中,保留的是原索引2对应的数值2,完全符合题目允许的输出要求。如果需要保留原索引0对应的2,只需将遍历顺序改为逆序,最终将结果反转即可。
内容的提问来源于stack exchange,提问作者crash
相关产品推荐
相关产品推荐

