numpy 配列に関数をマップする最も効率的な方法は何ですか? 現在、次の操作を実行しています:
import numpy as np
x = np.array([1, 2, 3, 4, 5])
# Obtain array of square of each element in x
squarer = lambda t: t ** 2
squares = np.array([squarer(xi) for xi in x])
しかし、これはおそらく非常に非効率的です。なぜなら、リストの理解を使用して新しい配列を Python リストとして構築してから、それを numpy 配列に戻すからです。もっと良い方法はないでしょうか?
ベストアンサー1
私は提案されたすべての方法に加えてnp.array(list(map(f, x)))
、perfplot
(私の小さなプロジェクトです)。
メッセージ #1: NumPy のネイティブ関数を使用できる場合は、それを使用してください。
ベクトル化しようとしている関数がすでにベクトル化されている場合(x**2
元の投稿の例のように)、それを使用すると他の方法よりもはるかに高速になります (対数スケールに注意してください)。
実際にベクトル化が必要な場合は、どのバリアントを使用するかはそれほど重要ではありません。
プロットを再現するためのコード:
import numpy as np
import perfplot
import math
def f(x):
# return math.sqrt(x)
return np.sqrt(x)
vf = np.vectorize(f)
def array_for(x):
return np.array([f(xi) for xi in x])
def array_map(x):
return np.array(list(map(f, x)))
def fromiter(x):
return np.fromiter((f(xi) for xi in x), x.dtype)
def vectorize(x):
return np.vectorize(f)(x)
def vectorize_without_init(x):
return vf(x)
b = perfplot.bench(
setup=np.random.rand,
n_range=[2 ** k for k in range(20)],
kernels=[
f,
array_for,
array_map,
fromiter,
vectorize,
vectorize_without_init,
],
xlabel="len(x)",
)
b.save("out1.svg")
b.show()