2016-03-31 63 views
3

Bool值的矩陣,例如writedlm布爾矩陣爲0,1矩陣

x = bitrand(2,3) 

如果我嘗試這個保存到一個文件:

writedlm("mat.txt", x) 

我得到矩陣truefalse。我想獲得一個01的矩陣(其中0代替false,1代替true)。有沒有一種簡單的方法來做到這一點,也許通過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更具有內存有效性。

+2

你也可以使用'Int8'來達到同樣的效果,但內存效率要高得多。試用800x800矩陣,「Int64」使用4.8MB,而「Int8」只使用0.6MB。 – niczky12

+0

這涉及將轉換矩陣的完整副本加載到內存中。我在循環內部執行'writedlm',所以我認爲性能影響太大。 – becko

+0

有沒有「map」的懶惰版本?我使用谷歌搜索,但找不到任何。 – becko

0

另一種選擇是稍快於副本數組UInt8上飛爲Array{UInt8, ndims(x)}(x),而不是應用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

我通常將「cast」這個詞理解爲Julia被稱爲「reinterpret」的含義,即以不同的方式查看內存中的相同位。然而,在這裏,你再次創建一個* new *矩陣。 –

+0

@ DavidP.Sanders我同意* cast *不應該創建一個副本,也許這裏不是最好的單詞(重寫爲* copy *)。如果'x'是一個'Array {Bool}','reinterpret(UInt8,x)'是最好的解決方案,然而'bitrand'返回一個'reinterpret'不支持的'BitArray'。 –