2016-03-31 9 views
3

ich eine Matrix aus Bool Werte haben, zum Beispielwritedlm eine Matrix von Bool als 0,1 Matrix

x = bitrand(2,3) 

Wenn ich versuche, diese in einer Datei zu speichern:

writedlm("mat.txt", x) 

ich eine Matrix von true und false. Ich möchte stattdessen eine Matrix von 0 und 1 bekommen (wobei 0 den Wert false und 1 den Wert true ersetzt). Gibt es einen einfachen Weg, um dies zu tun, vielleicht durch einige Optionen in writedlm, ohne die Datei Zeile für Zeile selbst zu schreiben?

+4

Versuchen Sie '1 * x', es erhält die numerische Version (vielleicht nicht super Speicher/Zeit effizient, aber gut genug für nicht" Big Data "Zeug). '0x1 * x' wird ein UInt8 mehr Speicher kompakt (aber wahrscheinlich langsamer). –

+1

@DanGetz Sie sollten das als Antwort posten. Es ist die einfachste Lösung. – becko

Antwort

3

1*x Versuchen Sie, es wird die numerische Version (vielleicht nicht super Speicher/Zeit effizient, aber gut genug für non "Big Data" stuff). 0x1*x wird ein UInt8 - mehr Speicher kompakt (aber wahrscheinlich langsamer).

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

nimmt jedes Element x und wandelt sie in eine Ganzzahl unter Verwendung des Int8 Funktion/Konstruktor.

Sie könnten auch andere Integer-Typen verwenden, aber Int8 ist mehr Speicher effizienter als zum Beispiel Int64.

+2

Sie können auch 'Int8' verwenden, was dasselbe erreichen würde, aber viel effizienter ist. Versucht es mit 800x800-Matrix und "Int64" verwendet 4,8 MB, während "Int8" nur 0,6 MB verwendet. – niczky12

+0

Dies beinhaltet das Laden einer vollständigen Kopie der konvertierten Matrix in den Speicher. Ich mache das "Writedlm" in einer Schleife, also denke ich, dass die Performance zu groß ist. – becko

+0

Gibt es eine faule Version von 'map'? Ich google, kann aber keine finden. – becko

0

Eine weitere Option, die schneller ist leicht zu Kopie ist das Array UInt8 on the fly als Array{UInt8, ndims(x)}(x), anstatt map Anwendung:

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

lief ich einige Tests schnell und es ist sightly schneller, je größer die Matrizen sind (zumindest in meinem Computer).

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 

Ausgänge:

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

Normalerweise verstehe ich das Wort "Besetzung" als Bedeutung, was in Julia "Reinterpret" genannt wird, d. H. Die gleichen Bits im Speicher auf andere Weise betrachten. Hier erstellen Sie jedoch wieder eine * neue * Matrix. –

+0

@ DavidP.Sanders Ich stimme zu, dass * cast * sollte keine Kopie erstellen, ist vielleicht nicht das beste Wort hier (um * copy * umformuliert). 'reininterpret (UInt8, x)' ist die beste Lösung, wenn 'x' ein' Array {Bool} 'ist, jedoch' bitrand' ein 'BitArray' zurückgibt, das von' reininterpret' nicht unterstützt wird. –