我需要在python中编写一个函数,它返回一个数字列表的有效测量值。如果距离最近的其他测量值小于0.1秒,则度量无效。此外,输出列表的长度应与输入列表的长度相同。
因此:
[5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
应该返回[True, True, True, False, False, False, True]
我已按以下方式解决问题:
list = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
newlist = []
for i, j in zip(list, list[1:]):
if j - i >= .1:
newlist.append(True)
else:
newlist.append(False)
问题是这会返回以下列表:
[True, True, True, False, False, True]
False
测量失踪。
如何以不同方式编写此代码?
答案 0 :(得分:2)
您的假设不正确。只有2次错误的测量。一个在10.37,一个在10.45。 10.34
的测量结果正常,因为它发生在前一个测量后几秒钟。
您的结果的值比输入列表少1,因为您要将值2比较为2。
这是典型的"间隔&值"问题。间隔比值少一个。
写这样的测试以获得更好的性能(列表理解):
measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
print([abs(measures[i+1]-measures[i])>0.1 for i in range(len(measures)-1)])
[True, True, True, False, False, True]
(您的代码会创建大量无用的临时列表。还要避免使用list
作为变量)
但是,如果你想使所有测量结果无效,那么过于接近,没有花哨的东西,有滑动窗口:
measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
result = [True] * len(measures)
for i in range(len(measures)-1):
validity = abs(measures[i+1]-measures[i])>0.1
if result[i]: # don't overwrite an already invalidated value
result[i] = validity
result[i+1] = validity
print(result)
[True, True, True, False, False, False, True]
详细说明:
result
数组(*
运算符,很好)validity
标记(True
或False
)result
已经False
,则表示上一次迭代已经使其无效,保持原样,否则设置为validity
validity
(i+1
索引)没有临时列表创建,应该足够快。
答案 1 :(得分:0)
我这样解决,第一次将虚拟有效值插入到列表的头部和尾部,以便稍后我们可以比较前后值。 然后开始执行检查不包括我们添加的虚拟的值。
# rename var name to lst, not recommended to use keyword list as var name
lst = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
lst2 = [lst[0]+1] + lst + [lst[-1]+1]
# use absolute function so we checking the absolute difference
newlist = [ abs(lst2[i]-lst2[i+1]) >= 0.1 and abs(lst2[i]-lst2[i-1]) >= 0.1 for i in range(1, len(lst)+1)]
# result newlist
# [True, True, True, False, False, False, True]
答案 2 :(得分:0)
另一种选择是使用numpy,在这种情况下不需要显式循环(Skycc的答案也是如此,但更简洁):
import numpy as np
a = np.array([5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5])
delta = np.diff(a) # forward difference
delta = np.insert(delta, 0, delta[0]) # duplicate the first delta at the beginning
delta = np.append(delta, delta[-1]) # duplicate last delta at the end
valid = np.abs(delta) >= 0.1 # boolean vector