首页 > 解决方案 > 在 python 中,有没有比 for 循环更快的方法来标记矩阵(3D 数组)?

问题描述

我在 Python 中编写了用于标记矩阵(3D 数组)的代码。代码的概念是

  1. 检查 3D 数组中的 2 x 2 x 2 矩阵(无论我想要什么大小)
  2. 如果矩阵有 1、2 和 3 作为元素,则矩阵中的所有元素都将更改为矩阵中的“最大唯一数 + 1”。

    import numpy as np
    
    def label_A(input_field):
    labeling_A = np.copy(input_field)
    labeling_test = np.zeros((input_field.shape))
    for i in range(0,input_field.shape[0]-1):
        for j in range(0,input_field.shape[1]-1):
            for k in range(0,input_field.shape[2]-1):
                test_unit = input_field[i:i+2,j:j+2,k:k+2]
                if set(np.unique(test_unit).astype(int)) >= set((1,2,3)):
                    labeling_test[i:i+2,j:j+2,k:k+2] = np.max(input_field)+1
                    labeling_A[labeling_test == np.max(input_field)+1] = np.max(input_field)+1
        return labeling_A
    

这是一个简单的 3D 矩阵示例代码。

example = np.random.randint(0, 10, size=(10, 10, 10))
label_example = label_A(example)
label_example

在我看来,代码本身没有问题,实际上它可以工作。但是,我很好奇有没有更快的方法来为此执行相同的功能?

标签: pythonarraysperformancenumpymatrix

解决方案


此实现返回建议的结果并在 1.8 秒内处理 (140,140,​​140) 大小的张量。

import numpy as np
from scipy.signal import convolve

def strange_convolve(mat, f_shape, _value_set, replace_value):
    _filter =np.ones(tuple(s*2-1 for s in f_shape))
    replace_mat = np.ones(mat.shape)
    for value in _value_set:
        value_counts = convolve((mat==value),_filter,mode='same')
        replace_mat*=(value_counts>0)
    mat[replace_mat==1]=replace_value
    return mat
example = np.random.randint(0, 8, size=(10, 10, 10))
print('same_output validation is '+str((strange_convolve(example,(2,2,2),(1,2,3),4) == label_A(example)).min()))

import time 
example = np.random.randint(0, 10, size=(140, 140, 140))
timer = time.time()
strange_convolve(example,(2,2,2),(1,2,3),4)
print(time.time()-timer)

1.8871610164642334


推荐阅读