pagetakaBlog

最近リフォームと鳥取県日南町の記事多め。写真、PC、ネット等の話題も

Python:Numpyで二次元配列(リスト)の列同士を入れ替え

列の入れ替え、列置換、列相互入れ替え

二次元配列(リスト)の列位置を相互交換、というのをやりたいともがいておりました。Excelシートの縦データを相互に交換する(A列↔B列)、といったイメージです。

具体的イメージでは、Xデータ(リスト)100人分は、名前、身長、国籍の順に並んでいた。Yデータ(リスト)500人分は、名前、国籍、身長の順に並んでいた、というようなことです。これらの並び順をそろえよう、という目論見です。
途中、一方は移動できたが、他方は元のまま、など失敗を繰り返しました。その例がこの下です。

入れ替え前

[[51 92 30]
[15 64 97]
[99 39 54]
[84 79 45]
[79 55 12]]

入れ替え後

[[51 92 92]
[15 64 64]
[99 39 39]
[84 79 79]
[79 55 55]]
Excelでいうと、B列とC列を入れ替えるつもりが、B列にC列の値が移動していませんでした。上書きされ消えてしまった…?

Pythonスクリプトで列を相互に入れ替えるとき、copy()を加えると、望んだ結果になりました。

上の結果(失敗)と下の結果(成功)を試したのは、下のスクリプトです。5行目の最後「.copy()」の有無が成否を分けています。

入れ替え前

[[73 55 95]
[32 85 87]
[14 48 36]
[71 95 52]
[46 66 67]]

入れ替え後

[[73 95 55]
[32 87 85]
[14 36 48]
[71 52 95]
[46 67 66]]

import numpy as np
a = (np.random.rand(5,3) * 100).astype(np.int32)
print(a)
print('-----')
a[0:, 2],a[0:,1] = a[0:,1],a[0:,2].copy()
print(a)

配列位置を指定する[0:,1]などでも戸惑い

リストがどうで、配列がどうで、オブジェクトがどうで、など爺にはよくわかりません。最初[0:,1]とかいうのを見たときさっぱりわかりませんでした。

まずこれは、二次元配列で[行, 列]について何かを記している、ということだそうです。Excelで例えると、「行」はシートの左端にある数字で、下に行くと大きくなるあれです。「列」は同じく、A、Bなどと表示され右に行くほどアルファベットが進むあれです。Excelで二次元配列を考えると、セル位置に似たような感じを持ちました。

0始まりの数字で、最初の位置は0です。これは、爺がN88-Basicやってた頃と同じみたい…。ところが「:」がありまして、面食らいました。[0:」というのは、最初の配列位置からずっと、ということみたいです。[0:, 1]という二次元配列は、「0行(最初の行・一番目の行・Excelなら第1行)からあとずっと、と、2番目の列(1は0の次で2番目、ExcelならB列)全部を指す」ということになるでしょうか…。0始まりでカウントする…ええ。

上のスクリプト、「a[0:, 2],a[0:,1] = a[0:,1],a[0:,2].copy()」は、aという二次元配列で、2列目全部(a[0:,1])の要素・データを3列目(a[0:,2])に移動し、もともとの3列目(a[0:,2])の要素・データを2列目に移動しなさい、というようなことになるかと思います。

参考

「,copy()」の書き方を見つけたURLを見失ってしまいました…。残念。
qiita.com

で、別の処理の方法もあるのだということで…。
note.nkmk.me