如何将[1,0,-1]标记的事件列表转换为[0,1]阶跃函数列表
实现方案
不需要写带缓存变量的遍历循环,用前缀和思路就能非常简洁地实现,同时天然支持多事件重叠的场景。
核心逻辑
之前尝试diff没达到预期,是因为这个需求本质是累计计数问题,不是差分问题:
- 起始标记
1:从当前位置开始进入事件状态 - 结束标记
-1:从下一个位置开始退出事件状态(给出的示例里,-1所在位置本身属于事件持续区间,符合这个规则) - 所有位置只要当前累计生效的事件数大于0,取值为1,否则为0
NumPy向量化实现
运行效率高,代码简洁:
import numpy as np event_list = [0,0,0,0,1,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,-1,0,0,0,0,0,1,0,0,0,0,0,-1,0,0] event_arr = np.array(event_list) n = len(event_arr) temp_arr = np.zeros(n, dtype=int) # 写入起始标记 temp_arr[event_arr == 1] = 1 # 结束标记后移一位,越界的直接丢弃 end_pos = np.where(event_arr == -1)[0] + 1 end_pos = end_pos[end_pos < n] temp_arr[end_pos] = -1 # 前缀和大于0即为事件持续期 step_list = (np.cumsum(temp_arr) > 0).astype(int).tolist()
运行结果和预期输出完全一致:
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]
纯Python标准库实现
不依赖第三方库,用itertools.accumulate就能实现,不需要手动维护状态变量:
from itertools import accumulate event_list = [0,0,0,0,1,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,-1,0,0,0,0,0,1,0,0,0,0,0,-1,0,0] n = len(event_list) temp = [0] * n for i, val in enumerate(event_list): if val == 1: temp[i] += 1 elif val == -1 and i + 1 < n: temp[i + 1] -= 1 step_list = [1 if cnt > 0 else 0 for cnt in accumulate(temp)]
内容的提问来源于stack exchange,提问作者K. W. Cooper
相关产品推荐
相关产品推荐

