我需要生成一个nX3的零数组,但其中一列的值在每行中交错(1.0)。
期望的输出:
n = 10
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.]])
我尝试对数组进行切片和重塑,但有些行包含全部零。
我的Attemtp:
n = 10
verts_color = np.zeros(3 * n)
verts_color[::4] = 1
verts_color.reshape((n,3))
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 0., 0., 0.],
[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 0., 0., 0.],
[ 1., 0., 0.],
[ 0., 1., 0.]])
我找不到一个例子或弄清楚如何自己解决这个问题,并希望有人能够帮我完成这个任务?
答案 0 :(得分:1)
方法#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
似乎运作良好。
答案 1 :(得分:1)
它有点古怪,但它的工作原理是你已经(垂直)堆叠的身份数组,但你需要根据n
调整行
n = 10
np.vstack([np.identity(3)]* (n//3 + 1))[:n, :]
或者,如果您希望提高效果,可以使用np.concatenate
:
np.concatenate([np.identity(3)]* (n//3 + 1), axis=0 )[:n, :]
对于 一般用例&提高性能 使用以下(n, m)
分别为行和列的内容。
np.concatenate([np.identity(m)]* (n//m + 1), axis=0 )[:n, :]
示例:
In [151]: n = 10
In [152]: np.vstack([np.identity(3)]* (n//3 + 1))[:n, :]
Out[152]:
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.]])
# number of columns
In [170]: m = 3
# number of rows
In [171]: n = 10
In [172]: np.concatenate([np.identity(m)]* (n//m + 1), axis=0 )[:n, :]
Out[172]:
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 [176]: def using_concatenate(n, m):
...: return np.concatenate([np.identity(m)]* (n//m + 1), axis=0 )[:n, :]
...:
In [177]: %timeit using_concatenate(n, m)
10000 loops, best of 3: 22.8 µs per loop
答案 2 :(得分:1)
import numpy as np
n = 10
x = np.zeros((n,3))
i = np.arange(n)
x[i, i%3] = 1