2016-03-31 1 views
3

、例えばwritedlm行列

x = bitrand(2,3) 

私は、ファイルにこれを保存しよう:

writedlm("mat.txt", x) 

私が手trueおよびfalseのマトリックス。私は代わりに01の行列を得たいと考えています(0は偽を置き換え、1は真を置き換えます)。 writedlmのいくつかのオプションによって、ファイルを行ごとに自分で書き込むことなく、これを行う簡単な方法はありますか?

+4

'1 * x'を試してみてください。数値バージョンを取得します(おそらく、スーパーメモリ/時間は効率的ではありませんが、"大きなデータ "以外のものには十分です)。 '0x1 * x'は、よりコンパクトなUInt8メモリを得ます(しかしおそらくは遅くなります)。 –

+1

@DanGetz答えとして投稿する必要があります。それは最も簡単な解決策です。 – becko

答えて

3

1*xを試してみて、それが数値バージョン(おそらくないスーパーメモリ/時間の効率的な、しかし非 "ビッグデータ" ものには十分)を取得します。 0x1*xはUInt8を取得します - よりコンパクトなメモリ(ただしおそらく遅い)。

5
writedlm("mat.txt", map(Int8,x)) 

xの各要素を取得し、Int8機能/コンストラクタを使用して整数に変換します。

他の整数型を使用することもできますが、Int8は、たとえばInt64よりもメモリ効率が優れています。 Array{UInt8, ndims(x)}(x)としてオンザフライUInt8

+2

同じことを実現する 'Int8'を使うこともできますが、メモリー効率ははるかに優れています。 800x800の行列で試してみたところ、 'Int64'は4.8MB、' Int8'は0.6MBしか使わなかった。 – niczky12

+0

変換された行列の完全なコピーをメモリにロードします。私はループ内でこの 'writedlm'をやっているので、パフォーマンスの影響は大きすぎると思います。 – becko

+0

'map'の遅延バージョンはありますか?私はグーグルであるが、何も見つけることができない。 – becko

0

わずかに速いですコピーにある別のオプション配列、むしろmapを適用するより:

>>> x = bitrand(100,100) 
>>> a = map(UInt8, x) 
>>> b = Array{UInt8, ndims(x)}(x) 
>>> all(a .== b) 
true 

私は迅速ないくつかのテストを実行し、それは見た目より速く大きくなっていますマトリックスは(少なくとも私のコンピュータでは)です。

for i in [10, 100, 1_000, 10_000] 
    x = bitrand(i,i) 
    println("$i x $i") 
    @time map(UInt8, x) 
    @time Array{UInt8, ndims(x)}(x) 
end 

出力:

10 x 10 
    0.000002 seconds (2 allocations: 208 bytes) 
    0.000006 seconds (2 allocations: 208 bytes) 
100 x 100 
    0.000053 seconds (2 allocations: 9.891 KB) 
    0.000018 seconds (2 allocations: 9.891 KB) 
1000 x 1000 
    0.001945 seconds (5 allocations: 976.703 KB) 
    0.001490 seconds (5 allocations: 976.703 KB) 
10000 x 10000 
    0.224491 seconds (5 allocations: 95.368 MB) 
    0.117774 seconds (5 allocations: 95.368 MB) 
+1

私はたいてい、「キャスト」という言葉は、ジュリアのものが「再解釈」と呼ばれていることを理解しています。つまり、メモリ内の同じビットを別の方法で見ます。ここでは、* new *行列を作成します。 –

+0

@ DavidP.Sanders私は*キャスト*がコピーを作成すべきではないことに同意します。おそらく、ここで最善の言葉ではありません(*コピー*に改訂)。 'x'が' Array {Bool} 'であれば' reinterpret(UInt8、x) 'が最適な解決策ですが、' bitrand'は 'reinterpret'でサポートされていない' BitArray'を返します。 –