2016-11-05 69 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