python - 在给定方向的 3D 数组中查找连接元素(运行)

标签 python numpy

我有一个 3D 数组,例如:

array = np.array([[[ 1.,  1.,  0.],
                   [ 0.,  0.,  0.],
                   [ 0.,  0.,  0.]],
                  [[1.,  0.,  0.],
                   [ 0.,  0.,  0.],
                   [ 0.,  0.,  0.]],
                  [[ 1.,  0.,  0.],
                   [ 0.,  0.,  0.],
                   [ 0.,  0.,  0.]]])

我需要为不同方向的每种可能尺寸找到连接的运行。 比如在(1,0,0)方向,水平方向,输出应该是:

> **Runs of size 1: 2
> **Runs of size 2: 1
> **Runs of size 3: 0

在 (0, 1, 0) 方向上,横跨纵轴:

> **Runs of size 1: 4
> **Runs of size 2: 0
> **Runs of size 3: 0

并且在 (0, 0, 1) 方向上,穿过 z 轴:

> **Runs of size 1: 1
> **Runs of size 2: 0
> **Runs of size 3: 1

有没有有效的方法来实现这个?

编辑:

我附上我正在处理的解决方案:

dire = np.array(([1, 0, 0], [0, 1, 0], [0, 0, 1])) # Possible directions
results = np.zeros((array.shape[0], len(dire)))  # Maximum runs will be 3

# Find all indices
indices = np.argwhere(array == 1) 

# Loop over each direction                 
for idire, dire in enumerate(dire):
    results[0, idire] = np.count_nonzero(array) # Count all 1 (conection 0)
    indices_to_compare = indices    

# Now we compare the list of indices with a displaced list of indices
    for irun in range(1, array.shape[0]):   
        indices_displaced = indices + dire*irun             
        aset = set([tuple(x) for x in indices_displaced])
        bset = set([tuple(x) for x in indices_to_compare])
        indices_to_compare = (np.array([x for x in aset & bset]))
        results[irun, idire] = len(indices_to_compare)

    # Rest the counts off bigger runs to the smaller ones, for duplicates
    for indx in np.arange(array.shape[0]-2,-1,-1):
        results[indx, idire] -=            
        np.sum(results[np.arange(array.shape[0]-1,indx,-1), idire])


print(results) # Each column is a direction, each row is the number of bins.

> [[ 2.  4.  3.]
   [ 1.  0.  1.]
   [ 1.  0.  0.]]

到目前为止,此代码不起作用,仅适用于方向 (0,1,0),没有任何联系且很简单。使用这种表示法,预期的输出应该是:

> [[ 2.  4.  1.]
   [ 1.  0.  0.]
   [ 0.  0.  1.]]

数组的比较来自this link .

编辑 2:

我对坐标的解释有误,似乎 np.argwhere 的结果 addint,(1,0,0) 超过了 z 轴,所以是预期的结果应该是:

> [[ 1.  4.  2.]
   [ 0.  0.  1.]
   [ 1.  0.  0.]]

最佳答案

这是一个沿轴向工作的矢量化解决方案:

def run_lengths(arr, axis):
    # convert to boolean, for speed - no need to store 0 and 1 as floats
    arr = arr.astype(bool)

    # move the axis in question to the start, to make the slicing below easy
    arr = np.moveaxis(arr, axis, 0)

    # find positions at the start and end of a run
    first = np.empty(arr.shape, dtype=bool)
    first[:1] = arr[:1]
    first[1:] = arr[1:] & ~arr[:-1]
    last = np.zeros(arr.shape, dtype=bool)
    last[-1:] = arr[-1]
    last[:-1] = arr[:-1] & ~arr[1:]

    # count the number in each run
    c = np.cumsum(arr, axis=0)
    lengths = c[last] - c[first]

    # group the runs by length. Note the above gives 0 for a run of length 1,
    # so result[i] is the number of runs of length (i + 1)
    return np.bincount(lengths, minlength=len(arr))

for i in range(3):
    print(run_lengths(array, axis=i))
[1 0 1]
[4 0 0]
[2 1 0]

关于python - 在给定方向的 3D 数组中查找连接元素(运行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45210272/

相关文章:

python - 动态填充列表或向量

python - 不可变的numpy数组?

python - 检查一对值是否在二维数组中 python

python - 具有多个输入的网络抓取并收集所需的总 margin

python - Python 中的微软翻译 API

python - 如何等待并在同一行python上打印

python - Pandas DataFrame [cell=(label,value)],分为 2 个独立的数据框

python - 如何从某一行开始将 numpy 数组写入 .txt 文件?

arrays - 比较 boolean numpy 数组

python - Bokeh 应用程序中的 throttle