ソフトな忘却力(121) みんな大好きNumPy配列のはらわた?

Joseph Halfmoon

「サイエンティフィックPythonのための」IDE、Spyder上にてScientific Python Lecturesの実習中。今回から再びNumPyです。Advancedなトピックらしいっす。過去回では闇雲に「配列」してましたが、今回はndarrayの中身、ハラワタ的なところに踏み込むみたい。大丈夫か?

※「 ソフトな忘却力」投稿順 Index はこちら

※今回Spyder IDEのバージョンを更新してます。Sypder IDEはWindows版 6.1.0 (AMD64)です。それにともないPython処理系もPython 3.12.11 (64-bit)にあがってます。

Scientific Python Lectures様のコースは例題だけでなく、エクササイズなども充実、それを全部順番に解いていったら必ずや立派な人になれるだろ~と思います。でも老い先短い年寄には量が多過ぎて多分死ぬまでに終わりません。適当な練習でお茶を濁してます。今回は「8.1 Life of ndarray」の「8.1.2 Block of memory」あたりです。

The array interface protocol

素人老人は、NumPy配列など、C言語の単純な配列構造にPythonからアクセスできるようにしたもんだろ~などと乱暴に想像していたのですが、違うみたいです。NumPyのndarrayというものは、以下のドキュメントで定義されている「プロトコル」に基づいておると。

https://numpy.org/doc/stable/reference/arrays.interface.html

そんな単純なもんでもなかったのね。

NumPy配列(ndarray)を作って中身を観察

とはいえ、凡人は具体例を数こなすことでしか身につきません。まして忘却力の老人ともなると、数こなしても忘れてしまうっと。どうするの?

まずは「2行3列」のfloat配列を作ってみましたぞ。smplArray0

さて、CTスキャンか超音波か、この配列の「腹の中」を探っていったところが以下に。smplArray1EC

どうも、smpl.dataというメンバがデータ実体を保持しているみたいです。分かりやすいお名前。ただしsmpl.dataはあるメモリ番地を指しているだけのようです。一方、smpl.dataをbytes型の文字列として取り出してみると、そこには何やら実体のあるデータが含まれているみたい。

そして、そもそも、dmpl.dataというメンバは smpl.__array_interface__という辞書の中に含まれているみたい。その中のキー ’data’ の0番目の要素のアドレスをみれば、先ほどの smpl.dataのアドレスとは違う。そこの関係は以下のようであるみたい。

    • smpl.data が指しているのはタプル。
    • タプルの最初の要素が「データ配列」の最初のアドレスをポイントしている
    • タプルの次の要素が、読み出しのみか否かのフラグ(Trueならリード・オンリ)

そういうことだったのね。しかし__array_interface__の中には他にも項目あり、調べてみると以下のようでした。

    • ‘strides’: None、NoneならC言語同様の連続メモリ領域。ここを弄れば「不連続」な領域も使える?知らんけど。
    • ‘descr’: [(”, ‘<f8’)]、 メモリレイアウトの詳細とのこと、デフォルト値が [(”, typestr)]ということで、ここの値はデフォのまま。
    • ‘typestr’: ‘<f8’、配列の型を示す部分、< はリトル・エンディアン(ということは >ならビック・エンディアンじゃろ)、fはfloat、末尾数字はバイト数
    • ‘shape’: (2, 3)、タプルで表された配列の各次元のサイズ
    • ‘version’: 3、 「インタフェース(プロトコル)」のバージョン。不適合なものを組み合わせるなっていうことだよね。

また、flagsというメンバもあり。smplArray2

冒頭に、C_CONTIGUOUSが真、F_CONTIGUOUSが偽とあるけど、このCはC言語、FはFortranということでよかですか? 同じ連続した領域に配列を割りつけても、CとFortranでは行と列の順番が違うので、ここではFの方は偽となるのでしょう。また、自前のデータ領域で、書き込みも可であると。

ということで(どういうことだ)、自前のデータ領域でない場合はどうよ、と疑問が浮かびました。しかし、「レクチャ」の中の人はそんなことはお見通しみたいで、例題がありました。真似っこしてみたところが以下に。smplArray3

バイト文字列領域をそのまま8ビット整数とみたてて、そこを参照するようにndarrayをしたててみると。すると自前データでもなく、書き込みも不可の配列が出来上がっとります。

まあ、ちょっとは分かった?スッキリした?

ソフトな忘却力(120) Python、Context managersでwith へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です