Во-первых, у вас есть пара проблем с вашим кодом, которые можно легко решить и ускорить.
Для каждого цикла вы пересчитываете np.max (input_field) +1 три раза.
Чем больше вашМатрица становится, влияние становится гораздо заметнее.Обратите внимание на разницу в тестах A и B.
Я попытался запустить тесты с помощью приведенного выше примера сгибания, и хотя он был быстрым, результаты никогда не были такими же, как в другом тесте (который в приведенной ниже настройке должен был бытьидентичны).Я считаю, что он ищет 1, 2 или 3 в блоке 3x3x3.
Метка A размером 10 --- 0: 00.015628
Метка B размером 10 --- 0: 00.015621
Метка F размером 10 --- 0: 00.015628
Метка A размером 50 --- 0: 15,984662
Метка B размером 50 --- 0: 10.093478
Метка F размером 50 --- 0: 02.265621
Метка A размером 80 --- 4: 02.564660
Метка B размером 80 --- 2: 29.439298
Метка Fс размером 80 --- 0: 09.437868
- - - - - - Отредактировано - - - - - - Сверточный метод определенно быстрее, хотя я полагаю, что есть некоторые проблемы с кодом, заданным Питером.
Label A with size of 10 : 00.013985
[[ 2 10 10 10 10 4 9 0 8 7]
[ 9 10 10 10 10 0 9 8 5 9]
[ 3 8 4 0 9 4 2 8 7 1]
[ 4 7 6 10 10 4 8 8 5 4]]
Label B with size of 10 : 00.014002
[[ 2 10 10 10 10 4 9 0 8 7]
[ 9 10 10 10 10 0 9 8 5 9]
[ 3 8 4 0 9 4 2 8 7 1]
[ 4 7 6 10 10 4 8 8 5 4]]
Label Flat with size of 10 : 00.020001
[[ 2 10 10 10 10 4 9 0 8 7]
[ 9 10 10 10 10 0 9 8 5 9]
[ 3 8 4 0 9 4 2 8 7 1]
[ 4 7 6 10 10 4 8 8 5 4]]
Label Convolve with size of 10 : 00.083996
[[ 2 2 10 8 4 10 9 0 8 7]
[ 9 10 0 4 7 10 9 10 10 9]
[ 3 8 4 0 9 4 2 10 7 10]
[ 4 7 10 5 0 4 8 10 5 4]]
ОП хотел вседля элементов матрицы 2x2x2 установлено более высокое значение.
Обратите внимание, что в текущей настройке свертки задаются отдельные элементы пространства, а не в шаблоне матрицы 2x2x2.
Ниже мой код:
import numpy as np
from scipy.signal import convolve
from pandas import datetime as dt
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
def label_B(input_field):
labeling_B = np.copy(input_field)
labeling_test = np.zeros((input_field.shape))
input_max = np.max(input_field)+1
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] = input_max
labeling_B[labeling_test == input_max] = input_max
return labeling_B
def label_Convolve(input_field):
_filter =np.ones([2,2,2])
replace_mat = np.ones(input_field.shape)
input_max = np.max(input_field)+1
for value in (1,2,3):
value_counts = convolve((input_field==value),_filter,mode='same')
replace_mat*=(value_counts>0)
input_field[replace_mat==1] = input_max
return input_field
def flat_mat(matrix):
flat = matrix.flatten()
dest_mat = np.copy(flat)
mat_width = matrix.shape[0]
mat_length = matrix.shape[1]
mat_depth = matrix.shape[2]
input_max = np.max(matrix)+1
block = 0
for w in range(mat_width*(mat_length)*(mat_depth-1)):
if (w+1)%mat_width != 0:
if (block+1)%mat_length == 0:
pass
else:
set1 = flat[w:w+2]
set2 = flat[w+mat_width:w+2+mat_width]
set3 = flat[w+(mat_width*mat_length):w+(mat_width*mat_length)+2]
set4 = flat[w+(mat_width*mat_length)+mat_width:w+(mat_width*mat_length)+mat_width+2]
fullblock = np.array([set1, set2, set3, set4])
blockset = np.unique(fullblock)
if set(blockset) >= set((1,2,3)):
dest_mat[w:w+2] = input_max
dest_mat[w+mat_width:w+2+mat_width] = input_max
dest_mat[w+(mat_width*mat_length):w+(mat_width*mat_length)+2] = input_max
dest_mat[w+(mat_width*mat_length)+mat_width:w+(mat_width*mat_length)+mat_width+2] = input_max
else:
block += 1
return_mat = dest_mat.reshape(mat_width, mat_length, mat_depth)
return(return_mat)
def speedtest(matrix,matrixsize):
starttime = dt.now()
label_A_example = label_A(matrix)
print(f'Label A with size of {matrixsize} : {dt.now() - starttime}')
print(label_A_example[0][0:4], '\n')
starttime = dt.now()
label_B_example = label_B(matrix)
print(f'Label B with size of {matrixsize} : {dt.now() - starttime}')
print(label_B_example[0][0:4], '\n')
starttime = dt.now()
label_Inline_example = flat_mat(matrix)
print(f'Label Flat with size of {matrixsize} : {dt.now() - starttime}')
print(label_Inline_example[0][0:4], '\n')
starttime = dt.now()
label_Convolve_example = label_Convolve(matrix)
print(f'Label Convolve with size of {matrixsize} : {dt.now() - starttime}')
print(label_Convolve_example[0][0:4], '\n')
tests = 1 #each test will boost matrix size by 10
matrixsize = 10
for i in range(tests):
example = np.random.randint(0, 10, size=(matrixsize, matrixsize, matrixsize))
speedtest(example,matrixsize)
matrixsize += 10