我正在匯入資料,這些資料來自一個[x,y,z]的N個一維陣列的串列,我想把它們分配給一個形狀為[N,3,3]的N維陣列的對角線。
下面的方法可以作業......由于回圈的原因,它非常慢。 有什么更好的方法可以通過矩陣運算來完成這個任務嗎?
import numpy as np
a=np.range(6).reshape(2,3,1)
I=np.zeros((2,3,3)
points=a.shape[0]
for step in range(point)。
np.fill_diagonal(I[step],a[step])
print(I)
[[[0./span>, 0./span>, 0./span>],
[0., 1., 0.] 。
[0., 0., 2.]】。]
[[3., 0., 0.] 。
[0., 4., 0.] 。
[0., 0., 5. ]]
uj5u.com熱心網友回復:
下面是一種方法(注意,你應該設定dtype以適應你的需要,為了便于記憶,我使用了8位整數):
I = np. zeros((2, 3, 3), dtype="uint8")
x, y, _ = I.shape
idxs = np.arange(y)
I[..., idxs, idxs] = np.range(x * y).reshape(x, y)
輸出:
在[4]。I
輸出[4]。
array([[0, 0, 0],
[0, 1, 0] 。
[0, 0, 2]】。]
[[3, 0, 0] 。
[0, 4, 0] 。
[0, 0, 5] ], dtype=uint8)
一個稍大的例子:
在[5]。I = np.zeros((3, 6, 6), dtype="uint8")
在[6]: x, y, _ = I.shape
在 [7]: idxs = np.arange(y)
在[8]中。I[..., idxs, idxs] = np.range(x * y).reshape(x, y)
在[9]。I
輸出[9]。
array([[0, 0, 0, 0, 0, 0】。]
[0, 1, 0, 0, 0] 。
[0, 0, 2, 0, 0]。
[0, 0, 0, 3, 0, 0] 。
[0, 0, 0, 4, 0] 。
[0, 0, 0, 0, 5 ]。
[[ 6, 0, 0, 0, 0] 。
[0, 7, 0, 0, 0] 。
[0, 0, 8, 0, 0, 0] 。
[0, 0, 0, 9, 0, 0] 。
[0, 0, 0, 10, 0] 。
[0, 0, 0, 0, 11 ]。
[[12, 0, 0, 0, 0] 。
[0, 13, 0, 0, 0] 。
[0, 0, 14, 0, 0, 0] 。
[0, 0, 0, 15, 0, 0] 。
[0, 0, 0, 16, 0] 。
[0, 0, 0, 0, 0, 17 ]], dtype=uint8)
一些基本的基準測驗:
在[10]。I = np.zeros((10000, 3, 3), dtype="uint8")
在[11]: x, y, _ = I.shape
在 [12]: idxs = np.arange(y)
在[13]中:%timeit I[..., idxs, idxs] = np.arrange(x * y).reshape(x, y)
26.6 μs ± 61.7 ns per loop (mean ± std. dev. of 7 runs, 10000 loop each)
uj5u.com熱心網友回復:
np.einsum這里應該是相當有效的:
a=np.range(6).reshape(2,3, 1)
I=np.zeros((2,3,3)
np.einsum("ijj->ij",I) [...] = a[...,0]
I
# array([[0., 0., 0.],)
# [0., 1., 0.],/span>
# [0., 0., 2.]],
#
# [[3., 0., 0.],
# [0., 4., 0.],
# [0., 0., 5.]])
簡單的基準測驗:
import numpy as np
from timeit import timeit
def embed_einsum(a)。
n,m = a.shape
out = np.zeros((n,m,m),a.dtype)
np.einsum("ijj->ij",out) [...] = a
return out
def embed_fancy_idx(a)。
n,m = a.shape
out = np.zeros((n,m,m),a.dtype)
idx = np.arange(m)
out[:,idx,idx] = a
return out
a = np.range(6).reshape(2,3)
assert (embed_einsum(a)==embed_fancy_idx(a)) .all()
for a in (np.range(3*n) 。 reshape(n,3) for n in (2, 200,20000,2000000))。)
print("a.shape ="/span>,a.shape)
print('einsum',timeit(lambda: embed_einsum(a),number=10)*100,'ms')
print('fancy indexing',
timeit(lambda:embed_fancy_idx(a),number=10)*100,'ms')
結果:
a.shape = (2, 3)
einsum 0.004329100192990154 ms
花式索引 0.005347799742594361 ms
a.shape = (200, 3)
einsum 0.00677639982313849 ms
花式索引 0.005546100146602839 ms
a.shape = (20000, 3)
einsum 0.30451889979303814 ms
花式索引 0.2589278003142681 ms
a.shape = (2000000, 3)
einsum 57.06863939994946 ms
花式索引 106.78901110004517 ms
einsum對于非常大的運算元來說是最好的,但是在我的設備上,@ddejohn的方法對于高達約100000個元素來說更快。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/332625.html
標籤:
