【问题标题】:Convert a matrix of positive integer numbers into a boolean matrix without loops将正整数矩阵转换为没有循环的布尔矩阵
【发布时间】:2020-01-14 18:40:05
【问题描述】:

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

我有一个二维矩阵a,形状为(rows, cols),带有正整数,我想定义一个矩阵b,如果a[i,j]=x,那么b[i,j+1] =b[i,j+2]=...=b[i,j+x]=1(b被初始化为一个零矩阵)。

您可以假设对于每个 j,x:j+x

例如,如果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]

是否可以在 Python 中使用 NumPy不使用循环来执行上述操作?

如果没有循环就无法做到这一点,有没有一种有效的方法来做到这一点? (rowscols 可以是很大的数字。)

【问题讨论】:

    标签: python numpy matrix


    【解决方案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,我认为这是不想要的。
    • @AndreasK。 IIUC 这由“您可以假设对于每个 j,x:j+x
    【解决方案2】:

    这是@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 循环,但我认为否则不可能这样做。

    【讨论】:

      猜你喜欢
      • 2019-02-06
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      相关资源
      最近更新 更多