wird vielleicht dabei helfen, dieses Beispiel mit 12 verschiedenen Array-Werte:
In [207]: x=np.arange(12).reshape(3,4).copy()
In [208]: x.flags
Out[208]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
...
In [209]: x.T.flags
Out[209]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : False
...
Die C order
Werte in der Reihenfolge sind, dass sie in generiert wurden, die transponierte diejenigen sind nicht
In [212]: x.reshape(12,) # same as x.ravel()
Out[212]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [213]: x.T.reshape(12,)
Out[213]: array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])
Sie bekommen können. 1d Ansichten von beiden
In [214]: x1=x.T
In [217]: x.shape=(12,)
die Form von x
c ein auch geändert werden.
In [220]: x1.shape=(12,)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-220-cf2b1a308253> in <module>()
----> 1 x1.shape=(12,)
AttributeError: incompatible shape for a non-contiguous array
Die Form der Transponierung kann jedoch nicht geändert werden. Die data
ist immer noch in der 0,1,2,3,4...
Reihenfolge, auf die nicht zugegriffen werden kann als 0,4,8...
in einem 1d-Array zugegriffen.
In [227]: x2=x1.copy()
In [228]: x2.flags
Out[228]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
...
In [229]: x2.shape=(12,)
Mit Blick auf strides
helfen könnten auch:
Aber eine Kopie x1
kann geändert werden. Ein Schritt ist, wie weit (in Bytes) es gehen muss, um zum nächsten Wert zu gelangen. Für eine 2D-Anordnung wird es 2 stride Werte sein:
In [233]: x=np.arange(12).reshape(3,4).copy()
In [234]: x.strides
Out[234]: (16, 4)
Um zu der nächsten Zeile zu erhalten, Schritt 16 Bytes, nur nächste Spalte 4.
In [235]: x1.strides
Out[235]: (4, 16)
Transponieren schalten nur die Reihenfolge der Schritte.Die nächste Zeile hat nur 4 Bytes - d. H. Die nächste Zahl.
Ändern der Form ändert auch die Schritte - nur Schritt durch den Puffer 4 Bytes gleichzeitig.
In [238]: x2=x1.copy()
In [239]: x2.strides
Out[239]: (12, 4)
Obwohl x2
sieht genauso aus wie x1
, es seinen eigenen Datenpuffer hat, mit den Werten in einer anderen Reihenfolge. Die nächste Spalte ist jetzt 4 Bytes über, während die nächste Zeile 12 (3 * 4) ist. die Schritte zum (4,)
In [240]: x2.shape=(12,)
In [241]: x2.strides
Out[241]: (4,)
Und wie bei x
, verringert um die Form bis 1d verändern.
Für x1
, mit Daten in der 0,1,2,...
Reihenfolge, gibt es keinen 1d Schritt, der 0,4,8...
geben würde.
__array_interface__
ist eine weitere nützliche Art und Weise Array-Informationen anzuzeigen:
In [242]: x1.__array_interface__
Out[242]:
{'strides': (4, 16),
'typestr': '<i4',
'shape': (4, 3),
'version': 3,
'data': (163336056, False),
'descr': [('', '<i4')]}
x1
Der Datenpufferadresse wird wie für x
gleich sein, mit der er die Daten teilt. x2
hat eine andere Pufferadresse.
Sie könnten auch mit dem Hinzufügen eines order='F'
Parameters zu den copy
und reshape
Befehlen experimentieren.
Ich denke, es wäre nützlich mit einer Notiz darüber, welcher Index in beliebiger Reihenfolge nebeneinander steht: letzter Index für 'C' und erster Index für' F'., Oder für ND-Arrays .. die späteren Indizes sind nahe miteinander als die erste für "C" und umgekehrt. – gauteh