2016-11-05 38 views
3

我需要在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

请解决您的压痕。 –

+0

您的问题的陈述意味着输出列表的长度应该比输入列表的长度小1.但是,下面的示例显示它们是相等的,而您获得的实际输出似乎是是正确的。请考虑重新说明问题。 –

回答

2

你的假设是不正确的。只有2个错误的测量。一个在10.37和一个在10.45。在10.34的测量结果是OK,因为它发生在前一个数秒之后。

你的结果具有1个比输入列表中的价值不大,因为你通过2

这是一个典型的“间隔&值”的问题比较值2。间隔比值更少。

编写测试这样获得更好的性能(列表理解):(代码创造了很多无用的临时名单的同时避免使用list作为变量)

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] 

但是,如果要作废它们太近,没有花哨的东西所有测量,用滑动窗口:

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标志(TrueFalse
  • 如果当前result已经False,就意味着之前的迭代已经失效了,离开原来的样子,否则设置为validity
  • 集 “下一步” 结果到validityi+1指数)

没有临时列表的创建,应该是速度不够快。

+0

OP的要求“最接近的其他测量距离0.1 [0.1]秒之外”似乎是双向的:由于'10.34'和'10.45'距离彼此小于0.1秒,*两个*都是无效的,因此OP的规定输出是正确的。你质疑我对OP的解释吗?你可能想给出与我的解释相对应的另一个答案,因为否则你的答案相当好。 –

+0

这是我的编程课的作业,它说应该有3个“假”测量。虽然这是真的,但10.34的测量发生在前一个测量的几秒之后,它在下一个测量之前不到0.1秒,因此也是False。 –

+0

好的,我添加了另一个版本,它创建了3个“假”值。没有列表理解(sob :)),但很简单。 –

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] 
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