【Julia】ベクトル間で一致している要素の index の取り出し方

こちらの記事では、ベクトルのマスクについて記載しました。このマスクするときに使用するベクトル(上述の記事中の index_set )ですが、入力データや計算結果に応じて動的に生成されることが多いです。その時のマスクに使用するベクトルの作成の仕方について備忘のために記載しておきます。

ベクトル内の値の index の取得方法

ベクトル内において、ある値だけ変更したい場合は結構な頻度であると思う。その場合は以下のようにすれば、その index 位置を取り出せます。

tmp_vec = [1,3,2,5,6,7,10,1]
ind = tmp_vec .== 1
println(ind)
println(tmp_vec[ind])

>Bool[1, 0, 0, 0, 0, 0, 0, 1]
>[1, 1]

これにより、値が 1 の部分は以下のように一斉に値を変更ができます。

tmp_vec[ind] .= 100
println(tmp_vec)

> [100, 3, 2, 5, 6, 7, 10, 100]

この操作は一般的によく行われると思います。

様々な値を一括で変更できる?

1 つの値に着目すれば、上述のような書き方で問題ないです。しかし、いくつかの異なる値を一斉に違う値に変更したい場合はどのようするか?その方法の 1 つをここで示します。

ベクトル間で一致している要素の index の取り出し方

例えば、tmp_vec 中の以下に示される値を一斉に別の値に変更することを仮定します。

[1,2,3]

この場合、どのように元のベクトルの index を指定すればよいだろうか?ここで役立つのが、.\in である。これを用いると、以下のように元ベクトルと上記のベクトル間において、要素が一致する部分の index が取り出せます。

ind = tmp_vec .∈ ([1,2,3],)
println(ind)
println(tmp_vec[ind])
> Bool[1, 1, 1, 0, 0, 0, 0, 1]
> [1, 3, 2, 1]

元のベクトルにおいて、1,2,3 の値がある位置に対して true となるような BitVector を取得できます。このようにして、ベクトル間で要素が一致している部分を探し出し、その要素の変更を一括で行えるようになります。

なお、上記の BitVector の形でなく index にしたい場合は、findall を用いて true の部分の index を取得すれば問題ないです。

println(findall(ind))
> [1, 2, 3, 8]

まとめ

ベクトル間の要素が一致する場合の index が知れるのは役立ちますね。忘れないようにしたいです。

この記事が気に入ったらサポートをしてみませんか?