将一个由正整数组成的矩阵转换为布尔矩阵,无需循环。

3
我是一名帮助翻译的助手。
以下是要翻译的内容:

我正在尝试使用NumPy在Python中编写代码。我不确定是否可能,但这是我想做的:

我有一个形状为(rows, cols)的2D矩阵a,其中包含正整数,并且我想定义一个矩阵b,使得如果a[i,j]=x,则b[i,j+1]= b[i,j+2]= ... = b[i,j+x]=1(b初始化为零矩阵)。

您可以假设对于每个j,x:j + x<=cols-1。

例如,如果a是:

[0 2 0 0]
[0 2 0 0]
[3 0 0 0]
[2 0 1 0]

那么b应该是:

[0 0 1 1]
[0 0 1 1]
[0 1 1 1]
[0 1 1 1]

在不使用循环的情况下,是否有可能使用NumPy在Python中完成上述操作?

如果没有循环无法完成,那么有没有一种高效的方法?(rowscols可以是大数字。)

2个回答

1
如果不使用循环不行的话,有没有一种高效的方法呢?(rowscols可能是大数)。 对不起,我不知道NumPy函数能否在您的情况下提供帮助,但我认为普通循环和数组索引应该非常快:
import numpy as np

a = np.array([
    [0, 2, 0, 0],
    [0, 2, 0, 0],
    [3, 0, 0, 0],
    [2, 0, 1, 0],
])

b = np.zeros(a.shape)
for i, x in enumerate(a.flat):
    b.flat[i + 1 : i + 1 + x] = 1

print(b)

哪个输出您期望的结果:

[[0. 0. 1. 1.]
 [0. 0. 1. 1.]
 [0. 1. 1. 1.]
 [0. 1. 1. 1.]]

我点了赞,但由于扁平化,例如如果a[0,3]为1,则b[1,0]将变为1,我认为这是不想要的。 - Andreas K.
根据我的理解,这被“您可以假设对于每个j、x:j + x <= cols-1”所覆盖。 - finefoot

0

这是@finefoot的稍微优化过的解决方案

aa = a.ravel()
b = np.zeros_like(aa)
for i, x in enumerate(aa):
    if x != 0:
        b[i + 1 : i + 1 + x] = 1
b = b.reshape(a.shape) 

这里有另一种解决方案,速度略快但可读性较差:
from itertools import chain

aa = a.ravel()
b = np.zeros_like(aa)
w = np.nonzero(aa)[0]
ranges = (range(s, e) for s, e in zip(w + 1, w + 1 + aa[w]))
for r in chain.from_iterable(ranges):
    b[r] = 1
b = b.reshape(a.shape)

在假设 j,x: j+x<=cols-1 的情况下,可以得到正确的结果。虽然两种解决方案都使用了 for 循环,但我认为没有其他方法可以解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接