我在numpy.ma-array中有状态信号(测量的是热泵)以及时间戳。我想要的是它所处的周期的长度以及它关闭的周期的长度。 (不是每天的运行时间或其他东西,这很容易......)
我有什么(示范,实际上我有超过16个月的分钟值......):
Time Value
12:00 0
12:01 1
12:02 1
...
12:29 1
12:30 1
12:31 0
...
12:41 0
12:42 1
...
13:01 1
13:02 0
...and so on
我想要的是输出:
running_time_was:
time value (=minutes)
12:31 30
13:10 20
off_time_was:
time value (=minutes)
12:42 11
(the exact timestamps doesn't matter so much, but there should be some)
我已经问过我认识的人谁知道python(他们不知道,也没有),并试图在互联网上搜索,但我只是不知道该搜索什么。所以也许有人可以至少给我一个提示,我可以输入谷歌? :)
ps:哇,stackoverflow很棒!我已经对作为被动用户的可用性感到惊讶,但是询问界面更好:)
答案 0 :(得分:3)
好吧,最后我得到了自己。但数以百万计的感谢乔金顿的回答,这给我带来了很大的启发,并教给我全部的东西:)
import numpy as np
def main():
# Generate some data...
t = np.linspace(0, 10*np.pi, 30)
x = np.sin(t)
condition = np.where(x>0,1,0)
onarray,offarray = on_off_times(condition)
print "Condition: ",condition
print "Ontimes: ",onarray
print "Offtimes: ",offarray
def on_off_times(condition):
changing=np.diff(condition) #complete array, -1 when tunring off, +1 when turning on
idx, = changing.nonzero() #Indices of changepoints
times=np.diff(idx) #'Times' between changes
times=np.r_[0,times] # The first time can't be calculated ->is set to 0
ontimes=np.where(changing[idx]<0,times,False) #When turning off: Was Ontime (times-array with "False" instead of offtimes)
offtimes=np.where(changing[idx]>0,times,False) #When turning on: Was Offtime
onarray=np.r_[changing.copy(),0] #copy the array with all the values and add 1(to have an "empty" array of the right size)
offarray=np.r_[changing.copy(),0]
np.put(onarray,idx,ontimes) #Put the times into it (at the changepoints)
np.put(offarray,idx,offtimes)
return onarray,offarray
main()
收益率:
Condition: [0 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
Ontimes: [0 0 2 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0]
Offtimes: [0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 0]
值得一提的是:
答案 1 :(得分:1)
基本上,你有一个布尔数组,你想找到连续区域的起点和终点。
避免循环遍历numpy数组的每个项目会好得多。
有几种不同的方法,但我通常会做类似的事情(我最初可能从here获得):
import numpy as np
def contiguous_regions(condition):
"""Finds contiguous True regions of the boolean array "condition". Returns
a 2D array where the first column is the start index of the region and the
second column is the end index."""
# Find the indicies of changes in "condition"
idx, = np.diff(condition).nonzero()
# Prepend or append the start or end indicies to "idx"
# if there's a block of "True"'s at the start or end...
if condition[0]:
idx = np.r_[0, idx]
if condition[-1]:
idx = np.r_[idx, len(condition)-1]
return idx.reshape((-1,2))
作为一个简单的例子:
import numpy as np
def main():
# Generate some data...
t = np.linspace(0, 6*np.pi, 100)
x = np.sin(t)
condition = x > 0
regions = contiguous_regions(condition)
lengths = regions[:,1] - regions[:,0]
for reg, length in zip(regions, lengths):
print 'Condition was True for {0} seconds'.format(length)
print ' From time {0}s to {1}s'.format(*reg)
def contiguous_regions(condition):
idx, = np.diff(condition).nonzero()
if condition[0]:
idx = np.r_[0, idx]
if condition[-1]:
idx = np.r_[idx, len(condition)-1]
return idx.reshape((-1,2))
main()
这会产生:
Condition was True for 16 seconds
From time 0s to 16s
Condition was True for 16 seconds
From time 33s to 49s
Condition was True for 16 seconds
From time 66s to 82s
答案 2 :(得分:0)
我会通过以下方式完成此操作:
# read data from file
dt = {'names' : ('ts', 'state'), 'formats' : ('S5','i4')}
data = np.loadtxt(datafn, dtype = dt)
# minutes counter
mc = 1
# current state, current timestamp
cs = data[0]['state']
ct = data[0]['ts']
# states dictionary
states = {1 : [], 0 : []}
for minute in data[1:]:
if cs != minute['state']:
states[cs].append([ct, mc])
mc = 0
cs = minute['state']
ct = minute['ts']
else:
mc += 1
# Printing the result
print 'On time'
for [ts, mc] in states[1]:
print '%s\t%i' % (ts, mc)
print 'Off time'
for [ts, mc] in states[0]:
print '%s\t%i' % (ts, mc)
非常未经测试,但你可以得到逻辑。
答案 3 :(得分:0)
你可以试试这个:
Since = 0
for i in range(1, Data.shape[0]):
#Switched off
if Data[i, 1] == 0.0 and Data[i - 1, 1] == 1.0:
print "{0} for {1}min".format(Data[i, 0], i - Since)
#Switched on
elif Data[i, 1] == 1.0 and Data[i - 1, 1] == 0.0:
Since = i
您遍历孔阵列(Data
),其在第一列中包含时间戳,在第二列中循环1.0
或0.0
,具体取决于加热器是打开还是关闭
您可以检测实际开/关值和前一个值的状态变化。根据这两个值,您可以看到加热器是Switched off
还是Switched on
。您需要做的就是将当前索引的值保存在Since
中,并获得加热器开启的时间。
使用以下脚本,您可以设置数据数组并运行上面的代码,看看它是如何工作的:
import datetime
import numpy as np
#Setting up OnOff array
OnOff = np.concatenate((np.zeros((7,)), np.ones((20,)), np.zeros((3,)), np.ones((5,)), np.zeros((4,)), np.ones((16,)), np.zeros((2,)), np.ones((2,)), np.zeros((1,))))
#Setting up time array
start = datetime.time(12, 00)
TimeStamps = []
for i in range(OnOff.size):
TimeStamps.append(datetime.time(12 + i/60, np.mod(i, 60)))
TimeStamps = np.array(TimeStamps)
#Concatenating both arrays to a single array
Data = np.hstack((np.reshape(TimeStamps, (TimeStamps.size, 1)), np.reshape(OnOff, (OnOff.size, 1))))
Since = 0
for i in range(1, Data.shape[0]):
#Switched off
if Data[i, 1] == 0.0 and Data[i - 1, 1] == 1.0:
print "{0} for {1}min".format(Data[i, 0], i - Since)
#Switched on
elif Data[i, 1] == 1.0 and Data[i - 1, 1] == 0.0:
Since = i
输出
12:27:00 for 20min
12:35:00 for 5min
12:55:00 for 16min
12:59:00 for 2min