Etant donné un NumPy array [~ # ~] a [~ # ~], quel est le moyen le plus rapide/le plus efficace d'appliquer le Même fonction , f, to chaque cellule ?
Supposons que nous assignions à A (i, j) le f (A (i, j)).
La fonction, f, n'a pas de sortie binaire, ainsi les opérations de masque (ing) ne vous aideront pas.
La double itération "évidente" (à travers chaque cellule) est-elle la solution optimale?
Vous pouvez simplement vectoriser la fonction, puis l’appliquer directement à un tableau Numpy chaque fois que vous en avez besoin:
import numpy as np
def f(x):
return x * x + 3 * x - 2 if x > 0 else x * 5 + 8
f = np.vectorize(f) # or use a different name if you want to keep the original f
result_array = f(A) # if A is your Numpy array
Il est probablement préférable de spécifier directement un type de sortie lors de la vectorisation:
f = np.vectorize(f, otypes=[np.float])
Une question similaire est: mappage d'un tableau NumPy à la place . Si vous pouvez trouver un func pour votre f (), utilisez le paramètre out.
Si vous travaillez avec des nombres et f(A(i,j)) = f(A(j,i))
, vous pouvez utiliser scipy.spatial.distance.cdist pour définir f comme distance entre A(i)
et A(j)
.
Je pense avoir trouvé une meilleure solution. L’idée de changer la fonction en python fonction universelle (voir documentation )), qui permet d’exercer un calcul parallèle sous le capot.
On peut écrire son propre ufunc
personnalisé en C, ce qui est sûrement plus efficace, ou en invoquant np.frompyfunc
, qui est la méthode d'usine intégrée. Après le test, cela est plus efficace que np.vectorize
:
f = lambda x, y: x * y
f_arr = np.frompyfunc(f, 2, 1)
vf = np.vectorize(f)
arr = np.linspace(0, 1, 10000)
%timeit f_arr(arr, arr) # 307ms
%timeit f_arr(arr, arr) # 450ms
J'ai également testé de plus grands échantillons, et l'amélioration est proportionnelle. Pour comparer les performances d'autres méthodes, voir cet article