如何用单个元素替换2d numpy数组中重复的连续元素

时间:2018-08-03 09:27:28

标签: python arrays numpy replace

我有一个形状为numpy的数组(1080,960)

[[0 0 255 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 255 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 255 255 ... 0 0 0]]

我想输出一个numpy数组,用一个0和255替换0和255的重复值

numpy数组表示二进制图像,其像素形式为BBBWWWWWWWBBBBBBWWW,其中B为黑色,W为白色。我想将其转换为BWBW。

示例

输入:

[[0,0,0,255,255,255,0,0,0,0],
 [255,255,255,0,0,0,255,255,255],
 [0,0,255,0,0,255,0,0,255]]

输出:

[[0,255,0],
 [255,0,255]
 [0,255,0,255,0,255]]

2 个答案:

答案 0 :(得分:1)

您可以遍历行并通过构建新数组来对元素进行分组,同时检查最后一个元素并仅在有差异时才追加。

功能如下:

def groupRow(row):
    newRow = [row[0]]
    for elem in row:
            if elem != newRow[-1]:
                    newRow.append(elem)
    return newRow

使用该函数的newRow迭代并替换形状中的每一行

答案 1 :(得分:1)

您不能输出2D numpy数组,因为输出行的长度可能不同。我会满足于numpy数组的列表。因此,首先让我们生成一些数据:

String

然后遍历每行:

extension Dictionary where Value: Sequence {

    var explode:[[Key:Value.Element]] {
        ...
    }
}

通过求和,我们仅检测变化发生的位置,然后使用这些索引img = np.random.choice([0,255], size=(1080, 960)) 选择连续的条纹中的起始元素。此解决方案比@DavidWinder的解决方案要简单和快捷(30 ms对150 ms)。

完全矢量化的解决方案可能会更快一些,但是代码会有些复杂。这将涉及到对数组进行展平,对索引进行散列和散列……并在最后应用out=[] for row in img: idx=np.ediff1d(row, to_begin=1).nonzero()[0] out.append(row[idx]) ,这不是一个很快的操作,因为它涉及到创建列表。因此,我认为这个答案足以在速度/代码简单性之间做出折衷。

编辑#1

如果首选输出是末尾加0的数组,则最好创建一个零数组并用idx列表的值填充。首先找出哪一行包含更多元素,然后创建数组:

np.split

然后遍历out列表和max_elms = np.max([len(x) for x in out]) arr = np.zeros((1080, max_elms), dtype=np.int32) ,用out列表中的值填充arr的值:

arr