2017-03-31 128 views
2

我正在編寫代碼和效率非常重要。 其實我需要2d數組,我在for循環中填充0和1。什麼更好,爲什麼?numpy數組爲零或空

  1. 製作空數組並填充「0」和「1」。這是僞代碼,我的陣列會更大。

  2. 使數組填充零,並使if()和如果不是零 - 放一個。

所以我需要的信息更重要的是效率: 1.把每一個元素「0」和「1」到空數組 或 2.如果(),然後(「如果」的效率)只放置「1」元素。

+3

最有效的方法是根本不使用'for'循環,而是將代碼向量化以便numpy可以完成這項工作。不要問我們什麼更快,時間自己。 – timgeb

+1

通常'if-then-else'比立即寫入值要慢。因爲'如果'傾向於減少鏈*的數量。不過,因爲Python本身就是一種解釋型語言。兩者都不會很有效。這就是爲什麼你更好地尋找讓numpy做這項工作的方法。 –

+0

我需要使用,因爲我需要從一個數組寫入其他數組的元素,但以特定的順序。我沒有找到其他方式來獲得我需要的特定順序而不是循環。 – Queen

回答

1
Ae = np.empty(10000) 
A0 = np.zeros((10000) 

在最初分配內存的方式上略有不同。但是,在任何時間差異將是次要的,如果你去和做類似

for i in range(10000): 
    Ae[i] = <some calc> 

for i in range(10000): 
    val = <some calc> 
    if val>0: 
     A0[i] = val 

如果我有這樣的循環,我會繼續使用np.zeros,也使用無條件分配。它使代碼更簡單,並且與其他發生的事情相比,時間差異將會很小。


採樣時間:

In [33]: def foo0(N): 
    ...:  A = np.empty(N,int) 
    ...:  for i in range(N): 
    ...:   A[i] = np.random.randint(0,2) 
    ...:  return A 
    ...: 
In [34]: def foo1(N): 
    ...:  A = np.zeros(N,int) 
    ...:  for i in range(N): 
    ...:   val = np.random.randint(0,2) 
    ...:   if val: 
    ...:    A[i] = val 
    ...:  return A 
    ...: 
分配10個0/1值

In [35]: foo0(10) 
Out[35]: array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0]) 
In [36]: foo1(10) 
Out[36]: array([0, 1, 1, 1, 1, 1, 1, 1, 0, 0]) 
In [37]: np.random.randint(0,2,10) 
Out[37]: array([0, 1, 1, 0, 1, 1, 1, 0, 0, 1]) 

倍的

3種方式:

In [38]: timeit foo0(1000) 
100 loops, best of 3: 4.06 ms per loop 
In [39]: timeit foo1(1000) 
100 loops, best of 3: 3.95 ms per loop 
In [40]: timeit np.random.randint(0,2,1000) 
... cached. 
100000 loops, best of 3: 13.6 µs per loop 

的2循環時間幾乎相同。

2
  • empty()不初始化內存,因此您的數組將填充垃圾,您將不得不初始化所有單元。
  • zeros()將所有元素初始化爲0.因此,如果最終結果包含很多零,這將節省您手動將所有這些數組元素設置爲零的時間。

我會用零()。無論如何,性能瓶頸將是你的python for循環。

幸運的是,現在numpy的作爲JIT編譯器,它可以把你照出和緩慢的Python for循環成機器代碼:

http://numba.pydata.org/

我試了一下。圍繞邊緣有點粗糙,但與裸露的Python代碼相比,加速可能非常壯觀。當然,最好的選擇是使用numpy進行矢量化,但是你並不總是有選擇。

1

最好創建一個零數組並使用if-else來填充它。即使是條件使得代碼變慢,重新定義空數組或將它與新向量連接起來,每次循環迭代操作都會更慢,因爲每次創建新大小的新數組時,都會將舊數組與新值向量一起復制。