我有一个信号列表(代表连续的测量):
signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
我认为信号只有在等于前面的n个测量值时才有效.
例如.如果我们只考虑2个测试验证(n=2),第一次信号从0变为1我们认为它仍然是0但是下一个测量,如果它再次为1则我们认为它仍然有效并使其成为1.然后我们需要2个测量0再次将其变为0等等...这里的信号为0和1以简化,但在我的应用中它们可以是其他整数.
期望的输出:
# For n = 2:
valid_s = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
# For n = 3:
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
# For n = 4:
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0]
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种pythonesque单行方式,但似乎无法找到所需的输出.我尝试了一些事情:
S = signals
# For n = 2
[S[i] if S[i] == S[i-1] else S[i-2] for i, _ in enumerate(S)]
# gives [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
# For n = 3
[S[i] if S[i] == S[i-1] == S[i-2] else S[i-3] for i, _ in enumerate(S)]
# gives [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
编辑:numpy如果因为它已经导入它更容易,我愿意接受.
我不认为有一个好方法可以使这个单线/列表理解.虽然您可以使用all列表的一部分来查看该值是否与n之前的值相同,但我没有看到确定哪个应该是最后一个有效值的好方法,如果不是.
相反,你可以使用一个古老的"多行"循环:
signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0]
n = 3
last_valid = 0
current = None
repeated = 0
res = []
for s in signals:
if s == current:
repeated += 1
else:
repeated = 1
current = s
if repeated >= n:
last_valid = s
res.append(last_valid)
Run Code Online (Sandbox Code Playgroud)
之后,res是[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
或者,稍微短一些,使用itertools.groupby; 结果是一样的:
last_valid = 0
res = []
for k, g in itertools.groupby(signals):
m = len(list(g))
if m >= n:
res.extend([last_valid] * (n-1) + [k] * (m-n+1))
last_valid = k
else:
res.extend([last_valid] * m)
Run Code Online (Sandbox Code Playgroud)