方法#1
def broadcasting_based(n, m): # n :number of cols, m : number of rows
return (np.mod(np.arange(m),n)[:,None] == np.arange(n)).astype(float)
方法2
def tile_based(n, m): # n :number of cols, m : number of rows
M = 1+((m-1)//n)
return np.tile(np.eye(n),M).T[:m]
方法3
def initialization_based(n, m): # n :number of cols, m : number of rows
M = 1+((m-1)//n)
r = np.arange(n)
out = np.zeros((M,n,n))
out[:,r,r] = 1
out.shape = (-1,n)
return out[:m]
一個多個初始化基於,較短的一個和利用步長的切 -
def initialization_based_v2(n, m): # n :number of cols, m : number of rows
out = np.zeros((m,n))
for i in range(n):
out[i::n,i] = 1
return out
樣品試驗 -
In [93]: broadcasting_based(n=3, m = 10)
Out[93]:
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.]])
In [94]: np.allclose(broadcasting_based(3,10), tile_based(3,10))
Out[94]: True
In [95]: np.allclose(broadcasting_based(3,10), initialization_based(3,10))
Out[95]: True
In [162]: np.allclose(broadcasting_based(3,10), initialization_based_v2(3,10))
Out[162]: True
運行測試
其他方法 -
# @kmario23's soln
def using_concatenate(m, n):
return np.concatenate([np.identity(m)]* (n//m + 1), axis=0)[:n, :]
# @Michael's soln
def initialization_modassign(m, n):
x = np.zeros((n,m))
i = np.arange(n)
x[i, i%m] = 1
return x
計時 -
In [188]: %timeit broadcasting_based(3,10000)
...: %timeit tile_based(3,10000)
...: %timeit initialization_based(3,10000)
...: %timeit initialization_based_v2(3,10000)
...: %timeit using_concatenate(3,10000)
...: %timeit initialization_modassign(3,10000)
...:
1000 loops, best of 3: 225 µs per loop
10000 loops, best of 3: 40.9 µs per loop
10000 loops, best of 3: 23.6 µs per loop
10000 loops, best of 3: 20.7 µs per loop
1000 loops, best of 3: 480 µs per loop
10000 loops, best of 3: 177 µs per loop
In [189]: %timeit broadcasting_based(5,10000)
...: %timeit tile_based(5,10000)
...: %timeit initialization_based(5,10000)
...: %timeit initialization_based_v2(5,10000)
...: %timeit using_concatenate(5,10000)
...: %timeit initialization_modassign(5,10000)
...:
1000 loops, best of 3: 238 µs per loop
10000 loops, best of 3: 63.6 µs per loop
10000 loops, best of 3: 33.3 µs per loop
10000 loops, best of 3: 33.3 µs per loop
1000 loops, best of 3: 275 µs per loop
10000 loops, best of 3: 176 µs per loop
因此,在性能initialization_based_v2
似乎工作得很好。
你的第一篇文章之前,你的編輯似乎當你寫像'(NP線完美運行。 mod(np.arange(n),3)[:,None] == np.arange(3))。astype(int)' – Logic1
@divakar但是,我仍然想知道python for'loop如何實現這樣的競爭表現。 – kmario23
@ kmario23它在'n'上迭代,其中'n'只是'3',與向量化一樣好。 – Divakar