2017-03-01 2 views
2

Ich bin ziemlich neu in Python. Was ich tun möchte, liest einige C-ähnliche Strukturen aus einer Binärdatei. Die Strukturen in dem c-Programm, das sie erzeugt, sind definiert als:Numpy komplizierte Datenstruktur

struct B{ 
    uint16 y; 
    uint8 c[SIZE2]; 
} 

struct A{ 
    uint32 x; 
    struct B b[SIZE1]; 
} 

Ich möchte in der Lage sein, alles A-structs zu lesen mit der NumPy Paket Funktion fromFile, aber ich habe keine Ahnung, wie aufruf eine geeignete Methode dtype, wie:

record = numpy.dtype([ 
    ("field1", numpy.uint8), 
    ("field2", numpy.uint16), 
    ("field3", numpy.uint32) 
]) 

mit einer solch komplizierten Datenstruktur.

Könnten Sie mir bitte helfen, es zu schreiben? Vielen Dank im Voraus!

+0

Haben Sie [hier] (https://docs.scipy.org/doc/numpy-1.10.1/user/basics.rec.html) gesucht? Ich bin mir nicht sicher, ob du so nisten kannst, oder zumindest weiß ich nicht wie. Auch, vielleicht [diese Frage] (http://stackoverflow.com/questions/9909399/nested-structured-numpy-array) ist verwandt, nicht sicher. –

Antwort

1

Dies ist ein wenig raten, da ich nicht viel mit C-Strukturen gearbeitet habe.

In [125]: SIZE1, SIZE2 = 3,4 

In [127]: dtB=np.dtype([('y',np.uint16),('c',np.uint8,(SIZE2,))]) 
In [128]: np.ones((2,), dtype=dtB) 
Out[128]: 
array([(1, [1, 1, 1, 1]), (1, [1, 1, 1, 1])], 
     dtype=[('y', '<u2'), ('c', 'u1', (4,))]) 
In [129]: _.itemsize 
Out[129]: 6 

In dieser Definition jeder Datensatz dieses Array besteht aus 6 Bytes, 2 für y Feld, 4 für das c Feld.

Dann Nest, das in einer A Definition

In [130]: dtA=np.dtype([('x',np.uint32),('b',dtB,(SIZE1,))]) 
In [131]: np.ones((2,), dtype=dtA) 
Out[131]: 
array([(1, [(1, [1, 1, 1, 1]), (1, [1, 1, 1, 1]), (1, [1, 1, 1, 1])]), 
     (1, [(1, [1, 1, 1, 1]), (1, [1, 1, 1, 1]), (1, [1, 1, 1, 1])])], 
     dtype=[('x', '<u4'), ('b', [('y', '<u2'), ('c', 'u1', (4,))], (3,))]) 
In [132]: _.itemsize 
Out[132]: 22 

Jeder Datensatz 4 Bytes für das x Feld hat, 3 * 6 für die 3 b Elemente.

In [133]: __.tobytes() 
Out[133]: b'\x01\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01' 

Und versuchen, das Array interessanter zu machen:

In [136]: A['x']=[1,2] 
In [139]: A['b']['y'] *= 3 
In [141]: A['b']['c'][0]=2 
In [142]: A['b']['c'][1]=3 
In [143]: A 
Out[143]: 
array([(1, [(3, [2, 2, 2, 2]), (3, [2, 2, 2, 2]), (3, [2, 2, 2, 2])]), 
     (2, [(3, [3, 3, 3, 3]), (3, [3, 3, 3, 3]), (3, [3, 3, 3, 3])])], 
     dtype=[('x', '<u4'), ('b', [('y', '<u2'), ('c', 'u1', (4,))], (3,))]) 
In [144]: A[0].tobytes() 
Out[144]: b'\x01\x00\x00\x00\x03\x00\x02\x02\x02\x02\x03\x00\x02\x02\x02\x02\x03\x00\x02\x02\x02\x02' 

Sind diese bytestrings im Einklang mit Ihren c struct?

+0

Das hat perfekt funktioniert. Vielen Dank! – neekogi