[英]Python Numpy array is slow(er) than list
我正在使用二維數組。 基本上只是嘗試對常量值進行元素明智的添加。 需要加快代碼速度,因此嘗試使用 numpy 數組而不是列表列表,但發現 numpy 速度較慢。 知道我做錯了什么嗎? 謝謝。
例如:
import time
import numpy as np
my_array_list = [[1,2,3],[4,5,6],[7,8,9]]
my_array_np = np.array(my_array_list)
n = 100000
s_np = time.time()
for a in range(n):
for i in range(3):
for j in range(3):
my_array_np[i,j] = my_array_np[i,j] + 5
end_np = time.time() - s_np
s_list = time.time()
for a in range(n):
for i in range(3):
for j in range(3):
my_array_list[i][j] = my_array_list[i][j] + 5
end_list = time.time() - s_list
print('my_array_np:', '\n', my_array_np, '\n')
print('my_array_list:', '\n',my_array_list, '\n')
print('time to complete with numpy:', end_np)
print('time to complete with list:', end_list)
輸出:
my_array_np:
[[500001 500002 500003]
[500004 500005 500006]
[500007 500008 500009]]
my_array_list:
[[500001, 500002, 500003], [500004, 500005, 500006], [500007, 500008, 500009]]
time to complete with numpy: 0.7831366062164307
time to complete with list: 0.45527076721191406
可以看到,使用列表進行此測試時,完成時間明顯更快,即 0.45 秒與 0.78 秒。 在這里 numpy 不應該明顯更快嗎?
假設您想向所有 3 的倍數的元素添加一些內容。我們通常會使用mask
,而不是迭代數組的所有元素
In [355]: x = np.arange(12).reshape(3,4)
In [356]: mask = (x%3)==0
In [357]: mask
Out[357]:
array([[ True, False, False, True],
[False, False, True, False],
[False, True, False, False]])
In [358]: x[mask] += 100
In [359]: x
Out[359]:
array([[100, 1, 2, 103],
[ 4, 5, 106, 7],
[ 8, 109, 10, 11]])
許多操作都是ufunc
,它們有一個where
參數
In [360]: x = np.arange(12).reshape(3,4)
In [361]: np.add(x,100, where=mask, out=x)
Out[361]:
array([[100, 1, 2, 103],
[ 4, 5, 106, 7],
[ 8, 109, 10, 11]])
快速numpy
要求我們考慮整個數組。 快速編譯的代碼對數組或數組塊進行操作。 數組上的 Python 級別迭代很慢,因為您發現列表上的迭代速度較慢。 訪問數組的單個值更昂貴。
對於這個小例子,這些全數組方法比數組迭代快,盡管它們仍然比列表迭代慢。 但是數組方法標量要好得多。
emmmmm...在當前情況下,列表推導似乎更快。但是當我添加 numba 時,np 會更快。
import dis
import time
import numpy as np
from numba import jit
my_array_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
my_array_np = np.array(my_array_list)
n = 1000000
# @jit
def fun1(my_array_np):
# it is inplace option
for a in range(n):
my_array_np += 5
s_np = time.time()
fun1(my_array_np)
end_np = time.time() - s_np
def fuc2(my_array_list):
for a in range(n):
my_array_list = [[i + 5 for i in j] for j in my_array_list]
return my_array_list
s_list = time.time()
my_array_list = fuc2(my_array_list)
end_list = time.time() - s_list
print('my_array_np:', '\n', my_array_np, '\n')
print('my_array_list:', '\n', my_array_list, '\n')
print('time to complete with numpy:', end_np)
print('time to complete with list:', end_list)
my_array_np:
[[500001 500002 500003]
[500004 500005 500006]
[500007 500008 500009]]
my_array_list:
[[500001, 500002, 500003], [500004, 500005, 500006], [500007, 500008, 500009]]
# use numba
time to complete with numpy: 0.27802205085754395
time to complete with list: 1.9161949157714844
# not use numba
time to complete with numpy: 3.4962515830993652
time to complete with list: 1.9761543273925781
[Finished in 3.4s]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.