[英]Why is numpy faster at finding non-zero elements in a matrix?
def nonzero(a):
row,colum = a.shape
nonzero_row = np.array([],dtype=int)
nonzero_col = np.array([],dtype=int)
for i in range(0,row):
for j in range(0,colum):
if a[i,j] != 0:
nonzero_row = np.append(nonzero_row,i)
nonzero_col = np.append(nonzero_col,j)
return (nonzero_row,nonzero_col)
與上面的代碼相比,上面的代碼要慢得多
(row,col) = np.nonzero(edges_canny)
如果我能得到任何關於如何提高速度以及為什么 numpy 函數要快得多的指導,那就太好了?
NumPy 函數優於 Python 類型的原因有兩個:
sum
。 在您的情況下,您也會做一些非常低效的事情:您附加到一個數組。 這是雙循環中間的一項非常昂貴的操作。 這是一個明顯的(也是不必要的)瓶頸。 只需將列表用作nonzero_row
和nonzero_col
並且僅在返回之前將它們轉換為數組,您就會獲得驚人的加速:
def nonzero_list_based(a):
row,colum = a.shape
a = a.tolist()
nonzero_row = []
nonzero_col = []
for i in range(0,row):
for j in range(0,colum):
if a[i][j] != 0:
nonzero_row.append(i)
nonzero_col.append(j)
return (np.array(nonzero_row), np.array(nonzero_col))
時間安排:
import numpy as np
def nonzero_original(a):
row,colum = a.shape
nonzero_row = np.array([],dtype=int)
nonzero_col = np.array([],dtype=int)
for i in range(0,row):
for j in range(0,colum):
if a[i,j] != 0:
nonzero_row = np.append(nonzero_row,i)
nonzero_col = np.append(nonzero_col,j)
return (nonzero_row,nonzero_col)
arr = np.random.randint(0, 10, (100, 100))
%timeit np.nonzero(arr)
# 315 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit nonzero_original(arr)
# 759 ms ± 12.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit nonzero_list_based(arr)
# 13.1 ms ± 492 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
即使它比 NumPy 操作慢 40 倍,它仍然比您的方法快 60 倍以上。 這里有一個重要的教訓:盡可能避免np.append
!
NumPy 優於替代方法的另一點是因為它們(大部分)使用最先進的方法(或“導入”它們,即 BLAS/LAPACK/ATLAS/MKL)來解決問題。 這些算法多年來(如果不是幾十年)已經針對正確性和速度進行了優化。 您不應該期望找到更快甚至類似的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.