2017-02-23 134 views
1

在對我們的源代碼庫進行了大量分析後,我們發現所有性能問題都是在循環遍歷一些巨大的列表時產生的。在各種情況下循環遍歷循環的最快方法

這是造成問題的代碼通道可作如下認定:

#ISSUE 1 
myList = [i for j, i in enumerate(myList) if j not in anotherList] 

#ISSUE 2 
TargetIndex = next((myList.index(n) for n in myList if n > someBoundary), len(myList)) 

#ISSUE 3 
def myFunction(): 
    for i in myList: 
     if abs(i) > someLimit: 
      return 0 
    return 1 

#ISSUE 4 
for n,i in enumerate(myList): 
    if abs(i) < someLimit: 
     myList[n] = 0 

我敢肯定,一些numpy專家們可以寫下四個一襯墊會導致很大的性能提升我們的應用。但是對於那些循環操作來說,或許還有更好的方法,我不知道它們是numpy

關於這個主題的任何建議,非常感謝。

+0

這些都是在列表上工作。爲什麼這個問題不成問題?如果他們是數組我們可能會建議更快的編譯操作。但爲此,我們需要知道形狀和dtype之類的東西。 – hpaulj

+0

嗨。所有列表元素的數據類型始終爲float,並且列表是平坦的(沒有列表)。 – Rickson

+0

欲瞭解更多的numpy上下文http://stackoverflow.com/q/42356625 – hpaulj

回答

2

第一個問題:做一個查找在set而不是list

anotherSet = set(anotherList) 
myList = [i for j, i in enumerate(myList) if j not in anotherSet] 

第二期:爲什麼計算的nindex當你在名單上已經迭代?使用enumerate

TargetIndex = next((i for i,n in enumerate(myList) if n > someBoundary), len(myList)) 

對於問題3 & 4,有沒有什麼可以做,但預先計算絕對值的列表,所以你不要在同一列表執行兩次。

abs_vals = [abs(n) for n in myList] 

所以例如第4段變爲:

for index,av in enumerate(abs_vals): 
    if av < someLimit: 
     myList[index] = 0 
+0

哇。這很快。非常感謝。我會試試看。 – Rickson

+0

工作很好。謝謝! – Rickson

2

警示作用,你必須改變比這些多很多,如果你想保持你的數據作爲numpy的陣列,但是這是你如何解決你的問題。

import numpy as np 

myArr=np.array(myList) 

#1 
myArr = myArr[np.in1d(np.arange(myArr.size), anotherList, invert = True)] 

#2 
TargetIndex = next(np.nonzero(myArr > someBoundary)[0].flat, myArr.size) 

#3 
def myFunction(): 
    return (np.abs(myArr) <= someLimit).astype(int) 

#4 
np.where(np.abs(myArr) < someLimit, 0, myArr)