JuliaでBitArray{n}をArray{Bool, n}に変換する方法
スパイク関連のニューラルネットを作っていたりすると特定の条件下でtrue/flaseを1 or 0に変換された配列を使いたくなる時がありますが、例えばiszero.やisone.で要素ごとに生成された乱数を1 or 0で纏めようとすると、BitArrayで出てきてしまいます。
spikes = rand(0:3,100) spikes = isone.(spikes) 結果: 100-element BitArray{1}:
これでも問題ないのですが、個人的にはなるべく配列で関数内部を処理したいことが多いです。例えば以下のように配列で処理したい関数を作ります。
function func_call!(spikes::Vector{Bool}) hogehogeな処理をする end
そして、先程のspikesを入力としてfunc_call!に入れると配列ではないのでmethod errorになってしまいます。
func_call!(spikes) MethodError: no method matching func_call!( ::BitArray{1}) Closest candidates are: func_call!(::Array{Bool,1}) at In[1]:1
BitArrayとArray{Bool}の違いについては以下のstackoverflowにも説明されています。
簡単に説明すると、Arrayはtrue/falseをそれぞれBoolとして格納していて、それぞれがUInt8で表現されています。8ビット=1バイトになりますので、Array{Bool}の場合は格納するためにNバイトの容量が必要になります。
一方で、BitArrayはtrue/falseを一つのビットで表現しており、8つのビットがUInt8に格納される方式になります。従って、Array{Bool}と比較するとN/8バイトしか必要としないメリットがあります。また、ビット操作を行うことができるのも魅力です。
違いをまとめると、以下のようになります。
・Array{Bool}...一つずつの要素をUInt8(1バイト)で表現
・BitArray...一つずつの要素を1ビットで表現したものを8つ集めてUInt8で表現
しかし、なるべくこちらとしては「配列で扱いたい」ので、BitArrayではなくArray{Bool}に変換したいです。変換方法についてですが、juliaはcollectで簡単に配列として変換することができます。
spikes = rand(0:3,100) spikes = collect(isone.(spikes)) 結果: 100-element Array{Bool,1}:
まとめ
今回はjuliaでのBitArrayとArray{Bool}の違いを説明して、BitArrayからArray{Bool}に変換する方法を説明しました。