我正在寻找一种算法来解析0s(表示False)和99s(表示True)列表中的变量,以将它们分为2类。此列表实质上指示了另一个列表中的值是否超过某个阈值,如下面的图1所示。
我想获得类别1的值的列表,其中包含检测到的第一个99s的第一段以及之后的每个99s的备用段。而类别2的值列表将包含检测到的99s的第2个初始段和此后的99s的每个备用段。作为示例,下面的图2和图3是我想要获得的Category 1和Category 2值。您可能会找到我的代码来复制下面的图。
图1:
图2:
图3:
df = pd.DataFrame(np.random.uniform(50,100,size=(100, 1)))
df2 = pd.DataFrame(np.random.uniform(50,100,size=(100, 1)))
zeros1 = pd.DataFrame(np.zeros(80))
zeros2 = pd.DataFrame(np.zeros(50))
zeros3 = pd.DataFrame(np.zeros(150))
zeros4 = pd.DataFrame(np.zeros(80))
zeros5 = pd.DataFrame(np.zeros(50))
df3 = pd.DataFrame(np.random.uniform(50,100,size=(100, 1)))
df4 = pd.DataFrame(np.random.uniform(50,100,size=(100, 1)))
df5=pd.concat([zeros1, df, zeros2, df2, zeros3, df3, zeros4, df4, zeros5 ], ignore_index=True)
times = pd.date_range('2012-10-01', periods=len(df5), freq='1min')
df6 = pd.concat([pd.DataFrame(times), df5], axis = 1, ignore_index=True)
segment = []
for i in range(0,len(df6)):
if df6.iloc[i,1]> 50:
segment.append(99)
else:
segment.append(0)
plt.plot(df6[0], df6[1])
plt.plot(df6[0], segment, color = 'r')
plt.xticks(rotation='vertical')
plt.show()
答案 0 :(得分:1)
此代码将循环访问0和99的列表,并记下每个99序列的开始和结束,并根据其奇偶性将其存储在其他列表中:
def get_alternate_segments(l):
state_v,state_p = (0,0) # cycling through states (0,0), (99,0), (0,1), (99,1)
segments = ([],[])
for i,v in enumerate(l):
if state_v == 0:
if v == 99:
start = i
state_v = 99
elif state_v == 99:
if v == 0:
end = i
segments[state_p].append((start, end))
state_v = 0
state_p = 1 - state_p
if state_v == 99:
end = len(l)
segments[state_p].append((start, end))
return segments
测试
>>> l = [0,99,99,99,0,0,99,99,0,0,0,99,0,99,0,99,99,99]
>>> get_alternate_segments(l)
([(1, 4), (11, 12), (15, 18)], [(6, 8), (13, 14)])
它是如何工作的??我们要记住,由于变量state_v
,我们当前看到的是0还是99s。我们还记得由于变量state_p
我们当前是否看到偶数或奇数段。
i
的值是该段的开始。i
的值记为该段的结尾,并将该段作为一对(start, end)
存储在segment[0]
或{{1}中},具体取决于平价。请注意,成对的segment[1]
与python的范围和列表切片约定一致。 即,从包含的(start, end)
到排除的start
。