Поскольку вы специально конвертируете входные данные f
в массив numpy, я предполагаю, что вы хотите использовать numpy. В этом случае распределение D_sub_h
должно измениться из списка в массив:
D_sub_h = np.empty_like(f)
Если мы предположим, что все, что находится за пределами вашего массива, это нули, то первая строка и последняя строка могут быть вычислены в качестве второй и отрицательной от второй до последней строки, соответственно:
D_sub_h[0, :] = f[1, :]
D_sub_h[-1, :] = -f[-2, :]
Остальная часть данных - это просто разница между следующим и предыдущим индексом в каждом местоположении, которая идиоматически вычисляется путем сдвига представлений: f[2:, :] - f[:-2, :]
. Эта формулировка создает временный массив. Вы можете избежать этого, используя np.subtract
в явном виде:
np.subtract(f[2:, :], f[:-2, :], out=D_sub_h[1:-1, :])
Все это занимает четыре строки в этой формулировке и полностью векторизовано, что означает, что циклы выполняются быстро под капот, без большинства накладных расходов Python:
def measure_blur(f):
D_sub_h = np.empty_like(f)
D_sub_h[0, :] = f[1, :]
D_sub_h[-1, :] = -f[-2, :]
np.subtract(f[2:, :], f[:-2, :], out=D_sub_h[1:-1, :])
return D_sub_h
Обратите внимание, что я возвращаю значение вместо его печати. Когда вы пишете функции, имейте привычку возвращать значение. Печать можно выполнить позже, и она фактически отбрасывает вычисление, если оно заменяет правильный возврат.
Показанный выше способ довольно эффективен в отношении времени и пространства. Если вы хотите написать один лайнер, который использует много временных массивов, вы также можете сделать:
D_sub_h = np.concatenate((f[1, None], f[2:, :] - f[:-2, :], -f[-2, None]), axis=0)