I have a time series representing regular queries into the functionality of a system, where 1 = working and 0 = not working. For example, expressing the time series as a list
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]
I am interested in calculating things like the mean time to failure (how long the system stays up) and the mean time to repair (how long the system stays down) and other similar statistics so what I want to do is count the sequential 1 entries and the sequential 0 entries. I want to trim off the beginning and end sets since, for the example above, I don't know when the system went down initially nor when it will come back up in the future. So the output I'd be looking to generate in this case would be
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]
I've written a script that does this but it seems a little bit awkward and I'm wondering if there's a better, more pythonic way to do it. Here's what I have.
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
yielding:
print count_times(U)
# [6, 4, 9, 2]
print count_times(U, down = True)
# [3, 3, 2]
This works, but I can't help but wonder if there is a cleaner way to do this?
My approach is similar to Ruben's, but it initially keeps the up and down times in the same list after applying groupby, so it's easier to trim the beginning and ending sets.
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
Result:
[6, 4, 9, 2]
[3, 3, 2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With