我有一个时间序列表示对系统功能的常规查询,其中 1 = working
和 0 = not working
。例如,将时间序列表示为列表
U = [0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,0]
我对计算平均故障时间(系统保持运行多长时间)和平均修复时间(系统保持停机多长时间)和其他类似统计数据很感兴趣,所以我想做的是计算顺序 1
条目和顺序 0
条目。我想剪掉开始和结束集,因为对于上面的示例,我不知道系统最初何时关闭,也不知道将来何时恢复。所以在这种情况下我希望生成的输出是
uptime = [6, 4, 9, 2] # 6 ones followed by zeros, then 4 ones followed by zeros, etc.
downtime = [3, 3, 2] # like uptime but ignoring zeros at indices [0,1] and [-1]
我已经编写了一个执行此操作的脚本,但它看起来有点笨拙,我想知道是否有更好、更 pythonic 的方法来执行此操作。这是我的。
def count_times(U, down=False):
if down:
U = [1 - u for u in U]
T = []
# Skip the first entry as you don't know when it started
m = U.index(0)
m += U[m:].index(1)
while m < len(U):
try:
T.append(U[m:].index(0))
m += U[m:].index(0)
m += U[m:].index(1)
except ValueError:
# skip the last entry as you don't know when it will end
return T
产量:
print count_times(U)
# [6, 4, 9, 2]
print count_times(U, down = True)
# [3, 3, 2]
这行得通,但我不禁想知道是否有更简洁的方法来做到这一点?
最佳答案
我的方法与 Ruben 的类似,但它最初在应用 groupby
后将上升和下降时间保持在同一个列表中,因此更容易修剪开始和结束集。
import itertools
U = [0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,0]
run_lengths = [(value, len(list(group))) for value, group in itertools.groupby(U)]
#discard first and last runs
run_lengths = run_lengths[1:-1]
#split runs into separate up and down time lists
uptime = [length for value, length in run_lengths if value == 1]
downtime = [length for value, length in run_lengths if value == 0]
print uptime
print downtime
结果:
[6, 4, 9, 2]
[3, 3, 2]
关于python - 计算python列表中相同条目的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23018316/