如何根据实际索引值屏蔽数组?
也就是说,如果我有一个10 x 10 x 30矩阵,我想在第一个和第二个索引相等时屏蔽数组。
例如,[1, 1 , :]
应该被屏蔽,因为1和1相等,但[1, 2, :]
不应该,因为它们不相同。
我只是问第三个维度,因为它类似于我当前的问题,可能会使事情复杂化。但我的主要问题是,如何根据索引值掩盖数组?
答案 0 :(得分:7)
通常,要访问索引的值,您可以使用np.meshgrid
:
i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij')
m.mask = (i == j)
此方法的优点是它适用于i
,j
和k
上的任意布尔函数。它比使用identity
特殊情况慢一点。
In [56]: %%timeit
....: i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij')
....: i == j
10000 loops, best of 3: 96.8 µs per loop
正如@Jaime指出的那样,meshgrid
支持sparse
选项,它没有那么多重复,但在某些情况下需要更多关注,因为它们不进行广播。它可以节省内存并加快速度。例如,
In [77]: x = np.arange(5)
In [78]: np.meshgrid(x, x)
Out[78]:
[array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]),
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]])]
In [79]: np.meshgrid(x, x, sparse=True)
Out[79]:
[array([[0, 1, 2, 3, 4]]),
array([[0],
[1],
[2],
[3],
[4]])]
因此,您可以使用sparse
版本,但您必须强制广播:
i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij', sparse=True)
m.mask = np.repeat(i==j, k.size, axis=2)
加速:
In [84]: %%timeit
....: i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij', sparse=True)
....: np.repeat(i==j, k.size, axis=2)
10000 loops, best of 3: 73.9 µs per loop
答案 1 :(得分:0)
在您想要遮挡对角线的特殊情况下,您可以使用np.identity()
函数返回沿对角线的函数。由于您有第三个维度,我们必须将第三个维度添加到单位矩阵:
m.mask = np.identity(10)[...,None]*np.ones((1,1,30))
可能有一种更好的方法来构造该数组,但它基本上堆叠了30个np.identity(10)
数组。例如,这相当于:
np.dstack((np.identity(10),)*30)
但速度较慢:
In [30]: timeit np.identity(10)[...,None]*np.ones((1,1,30))
10000 loops, best of 3: 40.7 µs per loop
In [31]: timeit np.dstack((np.identity(10),)*30)
1000 loops, best of 3: 219 µs per loop
和@Ophion的建议
In [33]: timeit np.tile(np.identity(10)[...,None], 30)
10000 loops, best of 3: 63.2 µs per loop
In [71]: timeit np.repeat(np.identity(10)[...,None], 30)
10000 loops, best of 3: 45.3 µs per loop