用两个 numpy 数组中的值的唯一组合来标记区域?

Rob*_*lor 2 python arrays numpy python-2.6 scipy

我有两个带有相同形状的标记的 2D numpya数组b。我想b通过类似于两个数组的GIS 几何并集的方式重新标记数组,以便为​​数组中具有唯一值组合的单元格a分配b新的唯一 ID:

在此输入图像描述

我不关心输出中区域的具体编号,只要这些值都是唯一的即可。我在下面附加了示例数组和所需的输出:我的真实数据集要大得多,两个数组都有范围从“1”到“200000”的整数标签。到目前为止,我已经尝试连接数组 ID 以形成唯一的值组合,但理想情况下,我希望以 1、2、3...等形式输出一组简单的新 ID。

import numpy as np
import matplotlib.pyplot as plt

# Example labelled arrays a and b
input_a = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
                    [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
                    [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
                    [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
                    [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
                    [0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0],
                    [0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
                    [0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

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

# Plot inputs
plt.imshow(input_a, cmap="spectral", interpolation='nearest')
plt.imshow(input_b, cmap="spectral", interpolation='nearest')

# Desired output, union of a and b
output = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 1, 1, 1, 2, 3, 3, 3, 3, 0, 0],
                   [0, 0, 1, 1, 1, 2, 3, 3, 3, 3, 0, 0],
                   [0, 0, 1, 1, 1, 4, 7, 7, 7, 7, 0, 0],
                   [0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
                   [0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
                   [0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

# Plot desired output
plt.imshow(output, cmap="spectral", interpolation='nearest')
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 5

如果我正确理解了情况,那么您正在寻找来自a和的独特配对b。因此,1froma1fromb在输出中将有一个唯一的标签;1froma3fromb在输出中会有另一个唯一的标签。另外看看问题中所需的输出,似乎这里还有一个额外的条件情况,即如果b为零,则输出也为零,无论唯一的配对如何。

以下实现试图解决所有这些问题 -

c = a*(b.max()+1) + b
c[b==0] = 0
_,idx = np.unique(c,return_inverse= True)
out = idx.reshape(b.shape)
Run Code Online (Sandbox Code Playgroud)

样本运行 -

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

In [22]: b
Out[22]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
       [0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
       [0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
       [0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
       [0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
       [0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

In [23]: out
Out[23]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 3, 5, 5, 5, 5, 0, 0],
       [0, 0, 1, 1, 1, 3, 5, 5, 5, 5, 0, 0],
       [0, 0, 1, 1, 1, 2, 4, 4, 4, 4, 0, 0],
       [0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
       [0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
       [0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)

示例图 -

# Plot inputs
plt.figure()                                                    
plt.imshow(a, cmap="spectral", interpolation='nearest')
plt.figure() 
plt.imshow(b, cmap="spectral", interpolation='nearest')

# Plot output
plt.figure()
plt.imshow(out, cmap="spectral", interpolation='nearest')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

在此输入图像描述