我有以下計算網格和向量相乘的代碼:
import numpy as np
Grid = np.ogrid[0:512, 0:512, 0:256]
Vec = np.array([1, 2, 3])
res = Vec @ Grid
警告是:
<stdin>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
為什么會發生警告,我應該如何以一種好的方式將其洗掉?
uj5u.com熱心網友回復:
警告的原因是Grid不同形狀的陣列((512, 1, 1)、(1, 512, 1)和(1, 1, 256))的串列。您可以通過指定dtypeas來使警告靜音object:
Vec @ np.array(Grid, dtype=object)
結果是一個(512, 512, 256)成形的 3D 陣列。
uj5u.com熱心網友回復:
這篇文章比我最初預期的要長,但我對ogridvsmgrid方法的性能很好奇。
如前所述,ogrid創建一個形狀不同的陣列串列:
In [67]: o=np.ogrid[0:3,0:2,0:4]; [1,2,3]@np.array(o,object)
...:
Out[67]:
array([[[ 0, 3, 6, 9],
[ 2, 5, 8, 11]],
[[ 1, 4, 7, 10],
[ 3, 6, 9, 12]],
[[ 2, 5, 8, 11],
[ 4, 7, 10, 13]]])
In [68]: o
Out[68]:
[array([[[0]],
[[1]],
[[2]]]),
array([[[0],
[1]]]),
array([[[0, 1, 2, 3]]])]
@適用于物件 dtype 陣列,但使用較慢的代碼,而不是快速的 BLAS。
mgrid制作一個陣列,該陣列可以@與合適的轉置一起使用(將乘積和維數放在最后:
In [69]: m=np.mgrid[0:3,0:2,0:4];
...: [1,2,3]@m.transpose(1,2,0,3)
Out[69]:
array([[[ 0, 3, 6, 9],
[ 2, 5, 8, 11]],
[[ 1, 4, 7, 10],
[ 3, 6, 9, 12]],
[[ 2, 5, 8, 11],
[ 4, 7, 10, 13]]])
In [71]: m.shape
Out[71]: (3, 3, 2, 4)
計時
In [72]: timeit o=np.ogrid[0:3,0:2,0:4]; [1,2,3]@np.array(o,object)
70.5 μs ± 5.04 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
In [73]: timeit m=np.mgrid[0:3,0:2,0:4]; [1,2,3]@m.transpose(1,2,0,3)
60.9 μs ± 77.1 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
分離出網格生成步驟,顯示了兩種的比較速度matmul:
In [74]: %%timeit o=np.ogrid[0:3,0:2,0:4]
...: [1,2,3]@np.array(o,object)
28.3 μs ± 103 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
In [75]: %%timeit m=np.mgrid[0:3,0:2,0:4];
...: [1,2,3]@m.transpose(1,2,0,3)
8.35 μs ± 146 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
使用更大的網格,比較優勢ogrid更大:
In [76]: timeit o=np.ogrid[0:512, 0:512, 0:256]; [1,2,3]@np.array(o,object)
254 ms ± 5.66 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [77]: timeit m=np.mgrid[0:512, 0:512, 0:256]; [1,2,3]@m.transpose(1,2,0,3)
3.74 s ± 193 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
ogrid因為這個大小只有 42.2 μs,而mgrid2.39 s。這意味著物件@ step 是 234 ms,而更高維的 float @ 是 1.23 s。
大多數物件 dtype 數學都是以串列理解速度完成的。所以@實際上是:
In [88]: sum([x*oo for x,oo in zip([1,2,3],o)])
Out[88]:
array([[[ 0, 3, 6, 9],
[ 2, 5, 8, 11]],
[[ 1, 4, 7, 10],
[ 3, 6, 9, 12]],
[[ 2, 5, 8, 11],
[ 4, 7, 10, 13]]])
In [89]: timeit sum([x*oo for x,oo in zip([1,2,3],o)])
18.6 μs ± 186 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [90]: o=np.ogrid[0:512, 0:512, 0:256]
In [91]: timeit sum([x*oo for x,oo in zip([1,2,3],o)])
227 ms ± 22 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
object所以這些速度和matmul基本一樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488955.html
標籤:麻木的
