今回は、プロトコルの1つであるバッファーを配列(ndarray)に変換する関数の1つである、np.frombuffer
関数について解説していきます。
Pythonが得意とする科学技術計算のアルゴリズムはNumPyもそうですが、高速化のためにCやFortranなどのコンパイルされた低レベルなコードが動いていることが多いです。このようなネイティブコードとPythonコードとをやりとりするために、Buffer Protocolという機構がPythonには備わっています。
例えば、bytesやarray.arrayなどのオブジェクトでは、Cレベルのバイト列を扱うことができるようになっています。
NumPyの関数にも、このようなバイト列を直接扱うことができます。np.frombuffer関数は、メモリのバイト列を直接読み込むため、大容量のデータをコピーせずに処理することが可能で、処理速度の高速化につながります。
np.frombuffer
まずは、この関数のAPIドキュメントから見ていきましょう。
numpy.frombuffer(buffer, dtype=float, count=-1, offset=0, …, like=None)
params:
|パラメータ名|型|概要|
|:———–|:-|:—|
|buffer
|buffer_like
バッファーに相当するもの|バッファーとして読み込むオブジェクトを指定します。|
|dtype
|data-type
データ型|(省略可能)初期値float
配列を返すときの要素のデータ型を指定します。|
|count
|int|(省略可能)初期値-1
いくつのアイテムを読み込むかを指定します。デフォルトの-1では全てのデータを読み込みます。|
|offset
|int|(省略可能)初期値0
バイト単位で、どこの地点からデータを読み込むかを指定します。|
|like
|array_like|NumPy配列以外の参照オブジェクトで生成します。__array_function__
プロトコルを継承しているオブジェクトを指定することができます|
returns:
渡されたバッファーを変換した配列を返します。
この関数は、引数bufferとして渡されたbufferを1次元配列に変換するものです。countやoffsetでデータを読み込む個数や開始点を指定できます。また、dtypeで返される配列のデータ型を指定することができます。
この関数を使うことでndarrayに高速変換することが期待できるので、大容量のデータを扱う方にはおすすめです。
今回は、音声ファイル(waveファイル形式)を配列に収納する時間を比べて見ます。まずは下準備です。今回使用したファイルは、録音したステレオサウンドのデータとなります。
変数dataに格納したファイルデータを配列に変換していきます。ここで、np.frombuffer
を使ってみます。同様の関数として、np.fromiter
があるのでそれとの処理速度の差を確かめて見ます。
np.frombuffer
のほうが100万倍ほど早い結果になりましたね。スケールが違いすぎてかなり戸惑うところですが、音声処理などをPythonでやりたい場合、まずはnp.frombuffer
関数で配列に格納したほうが処理速度の高速化が見込めます。