<p>numpy.vectorizeの実装は本質的にforループですか?</p>

作成日 2020年07月06日  ·  5コメント  ·  ソース: numpy/numpy

https://numpy.org/doc/1.18/reference/generated/numpy.vectorize.html
このチュートリアルでは、vectorizeの実装は本質的にforループであると述べています。 しかし、私が知る限り、ベクトル化された関数は
SIMDなので、numpy.vectorizeの実装は本質的にforループであると言うのは正確ですか? trueの場合、C言語でループが実装されているという理由だけで、ベクトル化されていない関数よりも高速ですか?

よろしくお願いします。

33 - Question

最も参考になるコメント

はい。 Python(numpyを使用)やMATLAB™などのインタープリター型数値配列プログラミング言語のコンテキストでは、「ベクトル化」を使用して、インタープリター型プログラミング言語の明示的なループを、すべての処理を行う関数(または演算子)に置き換えることを指すことがよくあります。内部でロジックをループします。 numpyでは、 ufuncこのロジックを実装します。 これは、複数の入力を同時に計算するSIMD CPU命令を使用することを指す「ベクトル化」の使用とは関係ありません。ただし、両方とも同様のメタファーを使用します。これらは「スカラー」の対応物に似ていますが、複数の入力値に対して計算を実行します。 1回の呼び出しで。

numpy.vectorize()を使用すると、通常、明示的なPython forループに比べて速度のメリットはそれほど多くありません。 その主なポイントは、Python関数をufuncに変換することです。これは、すべてのブロードキャストセマンティクスを実装し、任意のサイズの入力を処理します。 「ベクトル化」されているPython関数は、各要素の生の値をPythonオブジェクトに変換して関数に渡すだけでなく、ほとんどの時間を費やします。 np.vectorize(lambda x, y: x + y)が、ループ内とループの内容の両方でCであるufunc np.addほど高速であるとは期待できません。

全てのコメント5件

はい。 Python(numpyを使用)やMATLAB™などのインタープリター型数値配列プログラミング言語のコンテキストでは、「ベクトル化」を使用して、インタープリター型プログラミング言語の明示的なループを、すべての処理を行う関数(または演算子)に置き換えることを指すことがよくあります。内部でロジックをループします。 numpyでは、 ufuncこのロジックを実装します。 これは、複数の入力を同時に計算するSIMD CPU命令を使用することを指す「ベクトル化」の使用とは関係ありません。ただし、両方とも同様のメタファーを使用します。これらは「スカラー」の対応物に似ていますが、複数の入力値に対して計算を実行します。 1回の呼び出しで。

numpy.vectorize()を使用すると、通常、明示的なPython forループに比べて速度のメリットはそれほど多くありません。 その主なポイントは、Python関数をufuncに変換することです。これは、すべてのブロードキャストセマンティクスを実装し、任意のサイズの入力を処理します。 「ベクトル化」されているPython関数は、各要素の生の値をPythonオブジェクトに変換して関数に渡すだけでなく、ほとんどの時間を費やします。 np.vectorize(lambda x, y: x + y)が、ループ内とループの内容の両方でCであるufunc np.addほど高速であるとは期待できません。

詳細なご説明ありがとうございます。 しかし、明確にするために、例を挙げましょう。

import pandas as pd
import numpy as np
df = pd.DataFrame({'a': range(100000), 'b': range(1, 1000001)})
# method1
df.loc[:, 'c'] = df.apply(lambda x: x['a'] + x['b'], axis=1)
# method2 
df.loc[:, 'c'] = np.vectorize(lambda x, y: x + y)(df['a'], df['b'])
# method3
df.loc[:, 'c'] = np.add(df['a'], df['b'])

だからあなたの説明で、私は推測します

メソッド| Cでのループ| Cのループコンテンツ| SIMDを使用する
-| -| -| -
1 | ×| ×| ××
2 | √| ×| ××
3 | √| √| √

正しい?

np.addは、C doubleをPythonオブジェクトに変換したり、Python関数呼び出しのオーバーヘッドを回避したりするため、 np.vectorize(lambda x, y: x + y)よりも高速です。 AVX2拡張機能があるかどうかによっては、SIMD命令使用する可能性がありますが、それが高速である理由ではありません。

np.addは、C doubleをPythonオブジェクトに変換したり、Python関数呼び出しのオーバーヘッドを回避したりするため、 np.vectorize(lambda x, y: x + y)よりも高速です。 AVX2拡張機能があるかどうかによっては、SIMD命令を使用することも可能

わかった。 ありがとう。

numbaのvectorizeを使用して、Pythonのオーバーヘッドなしで並列に動作するufuncを生成できます。

https://numba.pydata.org/numba-doc/latest/user/vectorize.html

このページは役に立ちましたか?
0 / 5 - 0 評価