Ответ 1
Я не знаю какого-либо общего способа применения функций к N-D срезам массивов. Но есть два способа обойти это.
Если то, что вы хотите сделать, это применить производную 1D в каждой строке или столбце каждого 2D-фрагмента, это эквивалентно применению производной для каждого 1D-фрагмента, и вы можете использовать np.apply_along_axis:
values = np.arange(4)*np.arange(3)[:, None]+np.arange(2)[:, None, None]*2
>>> array([[[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6]],
[[2, 2, 2, 2],
[2, 3, 4, 5],
[2, 4, 6, 8]]])
np.apply_along_axis(np.gradient, 2, values)
>>> array([[[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.]],
[[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.]]])
Это отличает строки каждого двумерного среза. Чтобы различать каждый столбец, np.apply_along_axis(np.gradient, 2, values)
Если вы хотите сделать что-то, требующее двух измерений, вы можете получить его через параметры вещания и оси. Если, например, вы хотите V[i, j] = sqrt((V[i,j]-V[i, j-1])^2+V[i, j]-V[i-1, j])^2
для каждого фрагмента V
, вы можете сделать:
xdiffs = np.zeros_like(values)
xdiffs[:, 1:, :]= np.diff(values, axis=1)
ydiffs = np.zeros_like(values)
ydiffs[:, :, 1:] = np.diff(values, axis=2)
diffnorms = np.linalg.norm(xdiffs, ydiffs)
>>> array(
[[[ 0. , 0. , 0. , 0. ],
[ 0. , 1.41421356, 2.23606798, 3.16227766],
[ 0. , 2.23606798, 2.82842712, 3.60555128]],
[[ 0. , 0. , 0. , 0. ],
[ 0. , 1.41421356, 2.23606798, 3.16227766],
[ 0. , 2.23606798, 2.82842712, 3.60555128]]])
Немного громоздко получить правильные размеры, но обычно это будет наиболее эффективное решение.
В этих примерах используются нули на границах, если вам нужно что-то еще, вам нужно установить normdiff[:, :, 0]
и normdiff[:, 0, :]
на правильные значения границ.