Для тех, кто может жить без общего ответа, лучший ответ будет np.full_like(arr, val)
, который улучшится примерно на 20%, чем np.full(arr.shape, val)
И после поднятия этой проблемы автору,Я нашел лучшую золотую середину, которая достигает и общности, и в то же время довольно неплохо работает:
np.broadcast_arrays(x, f(x))[1]
и вот некоторый анализ времени:
arr = np.arange(1, 2, 0.0001).reshape(10, -1)
def master_f(x): return np.broadcast_arrays(x, f(x))[-1].copy('K')
def master_f_nocopy(x): return np.broadcast_arrays(x, f(x))[-1]
def vector_f(x): return np.vectorize(f)(x)
%timeit arr+1 # this takes about 10microsec
%timeit master_f(arr) # this takes about 40 mircrosec
%timeit master_f_nocopy(arr) # this takes about 20 microsec
Обратите внимание, что это позволяетприменять к проекционным функциям, таким как f(x,y):=y
, что не поддается помощи np.full_like
.
Более того, когда речь идет о более сложных функциях, таких как np.sin
и np.cos
, вы заметите, что разница между f(arr)
и master_f_nocopy(arr)
практически ничтожна.