python - 矢量化 : too many indices for array

标签 python numpy vectorization

a=b=np.arange(9).reshape(3,3)
i=np.arange(3)
mask=a<i[:,None,None]+3

b[np.where(mask[0])]
>>>array([0, 1, 2])

b[np.where(mask[1])]
>>>array([0, 1, 2, 3])

b[np.where(mask[2])]
>>>array([0, 1, 2, 3, 4])

现在我想对其进行矢量化并将它们全部打印在一起,我尝试

b[np.where(mask[i])]b[np.where(mask[i[:,None,None]])]

两者都显示IndexError:数组索引太多

最佳答案

In [165]: a
Out[165]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [166]: mask
Out[166]: 
array([[[ True,  True,  True],
        [False, False, False],
        [False, False, False]],

       [[ True,  True,  True],
        [ True, False, False],
        [False, False, False]],

       [[ True,  True,  True],
        [ True,  True, False],
        [False, False, False]]], dtype=bool)

因此,a(和b)是(3,3),而mask是(3,3,3)。

应用于数组的 bool 掩码会生成 1d(通过 where 应用时相同):

In [170]: a[mask[1,:,:]]
Out[170]: array([0, 1, 2, 3])

2d 掩码上的 where 生成一个 2 元素元组,它可以索引 2d 数组:

In [173]: np.where(mask[1,:,:])
Out[173]: (array([0, 0, 0, 1], dtype=int32), array([0, 1, 2, 0], dtype=int32))

其中 3d 掩模上的是一个 3 元素元组 - 因此出现索引过多错误:

In [174]: np.where(mask)
Out[174]: 
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2], dtype=int32),
 array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], dtype=int32),
 array([0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1], dtype=int32))

让我们尝试将 a 扩展到 3d 并应用 mask

In [176]: np.tile(a[None,:],(3,1,1)).shape
Out[176]: (3, 3, 3)
In [177]: np.tile(a[None,:],(3,1,1))[mask]
Out[177]: array([0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4])

值存在,但它们是连接在一起的。

我们可以计算mask每个平面中True的数量,并用它来分割 mask 图 block :

In [185]: mask.sum(axis=(1,2))
Out[185]: array([3, 4, 5])
In [186]: cnt=np.cumsum(mask.sum(axis=(1,2)))
In [187]: cnt
Out[187]: array([ 3,  7, 12], dtype=int32)

In [189]: np.split(np.tile(a[None,:],(3,1,1))[mask], cnt[:-1])
Out[189]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]

内部np.split使用Python级别的迭代。因此,mask 平面上的迭代可能同样好(在这个小示例中快 6 倍)。

In [190]: [a[m] for m in mask]
Out[190]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]
<小时/>

这指出了所需“矢量化”的一个基本问题,各个数组的形状为 (3,)、(4,) 和 (5,)。不同大小的数组有力地表明,真正的“矢量化”即使不是不可能,也是很困难的。

关于python - 矢量化 : too many indices for array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46781282/

相关文章:

python - 在OpenCV中获取多个小轮廓的外部轮廓

python - 需要关闭 python 套接字/在我的开发环境中查找当前正在运行的服务器

python - 根据传递的变量更改 HTML 表格中的颜色

python - 向量化 numpy 折扣计算

python - Numpy distutils 指南

r - 更有效的 which() 或 match() 策略

Python:在循环中向量化矩阵乘法?

python-3.x - 不了解 sklearn 的 HashingVectorizer

python - 将两个 Spark mllib 管道连接在一起

python - 二维数组每一列的外积形成一个三维数组 - NumPy