cod*_*iac 5 python numpy vectorization
我的 google-fu 失败了!我有一个 10x10 numpy 数组,初始化如下0:
arr2d = np.zeros((10,10))
Run Code Online (Sandbox Code Playgroud)
对于 中的每一行arr2d,我想将 3 个随机列分配给1。我可以使用循环来完成此操作,如下所示:
for row in arr2d:
rand_cols = np.random.randint(0,9,3)
row[rand_cols] = 1
Run Code Online (Sandbox Code Playgroud)
输出:
array([[ 0., 0., 0., 0., 0., 0., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 0., 1., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.],
[ 1., 0., 0., 1., 1., 0., 0., 0., 0., 0.],
[ 1., 0., 1., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 1., 0., 1., 0.],
[ 0., 0., 1., 0., 1., 0., 0., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 0., 1., 1., 0., 0.],
[ 0., 1., 0., 0., 1., 0., 0., 1., 0., 0.]])
Run Code Online (Sandbox Code Playgroud)
有没有办法利用 numpy 或数组索引/切片以更 Pythonic/优雅的方式实现相同的结果(最好用 1 或 2 行代码)?
一旦您使用 进行了arr2d初始化arr2d = np.zeros((10,10)),您就可以使用矢量化方法,如下所示two-liner-
# Generate random unique 3 column indices for 10 rows
idx = np.random.rand(10,10).argsort(1)[:,:3]
# Assign them into initialized array
arr2d[np.arange(10)[:,None],idx] = 1
Run Code Online (Sandbox Code Playgroud)
或者如果你喜欢这样的话,就可以把所有东西都抽筋——
arr2d[np.arange(10)[:,None],np.random.rand(10,10).argsort(1)[:,:3]] = 1
Run Code Online (Sandbox Code Playgroud)
样本运行 -
In [11]: arr2d = np.zeros((10,10)) # Initialize array
In [12]: idx = np.random.rand(10,10).argsort(1)[:,:3]
In [13]: arr2d[np.arange(10)[:,None],idx] = 1
In [14]: arr2d # Verify by manual inspection
Out[14]:
array([[ 0., 1., 0., 1., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 1., 1., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 1., 0., 1.],
[ 0., 1., 1., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0., 0., 1., 0., 0.],
[ 1., 0., 0., 0., 0., 1., 0., 0., 1., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 1., 0., 1.],
[ 1., 0., 0., 0., 0., 0., 1., 0., 1., 0.],
[ 1., 0., 0., 1., 0., 0., 0., 0., 1., 0.],
[ 0., 1., 0., 1., 0., 0., 0., 0., 0., 1.]])
In [15]: arr2d.sum(1) # Verify by counting ones in each row
Out[15]: array([ 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.])
Run Code Online (Sandbox Code Playgroud)
注意:如果您正在寻找性能,我建议使用np.argpartition中列出的基于方法this other post。