Чтобы ускорить код, вы можете сначала создать x_plot
и y_plot
вне циклов, а не создавать их несколько раз каждый:
#this would be outside of the loops
num = 5
lin_col = np.array([np.linspace(i, origin_col, num) for i in range(cols)])
lin_row = np.array([np.linspace(i, origin_row, num) for i in range(rows)])
, затем вы можете получить к ним доступ в каждомцикл по x_plot = lin_col[col]
и y_plot = lin_row[row]
Во-вторых, вы можете избежать обоих циклов, используя map_coordinates
для более чем одного v_stack
для каждой пары (row
, col
).Для этого вы можете создать все комбинации x_plot
и y_plot
, используя np.tile
и np.ravel
, например:
arr_vs = np.vstack(( np.tile( lin_row, cols).ravel(),
np.tile( lin_col.ravel(), rows)))
Обратите внимание, что ravel
не используется в одном и том же месте каждый раз, чтобы получить все комбинации.Теперь вы можете использовать map_coordinates
с этими arr_vs
и reshape
результатом с числом rows
, cols
и num
, чтобы получить каждый interpolated_line
в последней оси 3D-массива:
arr_map = map_coordinates(m, arr_vs, order=1, mode='nearest').reshape(rows,cols,num)
Наконец, вы можете использовать np.max
и np.argmax
на последней оси arr_map
, чтобы получить результаты m_max
и m_dist
.Таким образом, весь код будет:
import numpy as np
from scipy.ndimage import map_coordinates
m = np.array([
[10,10,10,10,10,10],
[9,9,9,10,9,9],
[9,8,9,10,8,9],
[9,7,8,0,8,9],
[8,7,7,8,8,9],
[5,6,7,7,6,7]])
origin_row = 3
origin_col = 3
rows, cols = m.shape
num = 5
lin_col = np.array([np.linspace(i, origin_col, num) for i in range(cols)])
lin_row = np.array([np.linspace(i, origin_row, num) for i in range(rows)])
arr_vs = np.vstack(( np.tile( lin_row, cols).ravel(),
np.tile( lin_col.ravel(), rows)))
arr_map = map_coordinates(m, arr_vs, order=1, mode='nearest').reshape(rows,cols,num)
m_max = np.max( arr_map, axis=-1)
m_dist = np.argmax( arr_map, axis=-1)
print (m_max)
print (m_dist)
, и вы получите, как и ожидалось:
#m_max
array([[10, 10, 10, 10, 10, 10],
[ 9, 9, 10, 10, 9, 9],
[ 9, 9, 9, 10, 8, 9],
[ 9, 8, 8, 0, 8, 9],
[ 8, 8, 7, 8, 8, 9],
[ 7, 7, 8, 8, 8, 8]])
#m_dist
array([[0, 0, 0, 0, 0, 0],
[0, 0, 2, 0, 0, 0],
[0, 2, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 2, 0, 0, 0, 0],
[1, 1, 2, 1, 2, 1]])
РЕДАКТИРОВАТЬ: lin_col
и lin_row
связаны, так что вы можете сделать быстрее:
if cols >= rows:
arr = np.arange(cols)[:,None]
lin_col = arr + (origin_col-arr)/(num-1.)*np.arange(num)
lin_row = lin_col[:rows] + np.linspace(0, origin_row - origin_col, num)[None,:]
else:
arr = np.arange(rows)[:,None]
lin_row = arr + (origin_row-arr)/(num-1.)*np.arange(num)
lin_col = lin_row[:cols] + np.linspace(0, origin_col - origin_row, num)[None,:]