Die Reihenfolge, in der sie Dinge tun - umformen, Schritte ändern und eine Kopie erstellen - unterscheidet sich, aber sie machen dasselbe.
Ich möchte __array_interface__
verwenden, um zu sehen, wo sich der Datenpuffer befindet, und andere Änderungen. Ich nehme an, ich sollte die flags
hinzufügen, um die order
zu sehen. Aber wir/Sie wissen, dass transpose
die Reihenfolge bereits auf F
ändert, oder?
In [549]: x=np.arange(6).reshape(2,3)
In [550]: x.__array_interface__
Out[550]:
{'data': (187732024, False),
'descr': [('', '<i4')],
'shape': (2, 3),
'strides': None,
'typestr': '<i4',
'version': 3}
Transponierte ist eine Ansicht, mit unterschiedlicher Form, Schritten und Reihenfolge:
In [551]: x.T.__array_interface__
Out[551]:
{'data': (187732024, False),
'descr': [('', '<i4')],
'shape': (3, 2),
'strides': (4, 12),
'typestr': '<i4',
'version': 3}
Ravel mit anderen Reihenfolge ist eine Kopie (verschiedene Datenpufferzeiger)
In [552]: x.ravel(order='F').__array_interface__
Out[552]:
{'data': (182286992, False),
'descr': [('', '<i4')],
'shape': (6,),
'strides': None,
'typestr': '<i4',
'version': 3}
Transponierte Ravel ist auch eine Kopie. Ich denke, der gleiche Datenzeiger ist nur ein Fall von Speicherwiederverwendung (da ich nicht zu einer Variablen zuweisen) - aber das kann überprüft werden.
In [553]: x.T.ravel().__array_interface__
Out[553]:
{'data': (182286992, False),
'descr': [('', '<i4')],
'shape': (6,),
'strides': None,
'typestr': '<i4',
'version': 3}
fügen Sie den reshape:
In [554]: x.T.ravel().reshape(2,3).__array_interface__
Out[554]:
{'data': (182286992, False),
'descr': [('', '<i4')],
'shape': (2, 3),
'strides': None,
'typestr': '<i4',
'version': 3}
In [555]: x.ravel(order='F').reshape(2,3).__array_interface__
Out[555]:
{'data': (182286992, False),
'descr': [('', '<i4')],
'shape': (2, 3),
'strides': None,
'typestr': '<i4',
'version': 3}
Ich denke, es gibt eine implizite 'ravel' in reshape:
In [558]: x.T.reshape(2,3).__array_interface__
Out[558]:
{'data': (182286992, False),
'descr': [('', '<i4')],
'shape': (2, 3),
'strides': None,
'typestr': '<i4',
'version': 3}
(ich sollte diese Beispiele überarbeiten dieses Speichers Wiederverwendung Mehrdeutigkeit loszuwerden .) In jedem Fall erfordert die Umformung nach der Transponierung die gleiche Speicherkopie, die ein Umbruch mit der Reihenfolgeänderung ausführt. Und soweit ich das beurteilen kann, ist nur eine Kopie für jeden Fall erforderlich. Die anderen Operationen beinhalten nur Änderungen an Attributen wie Form.
Kann sein, es klarer ist, wenn wir auf den Feldern sehen nur
In [565]: x.T
Out[565]:
array([[0, 3],
[1, 4],
[2, 5]])
Im T
wir noch durch das Array in numerischer Reihenfolge treten kann. Aber nach der Umformung ist die 1
nicht irgendwo in der Nähe der 0
. Offensichtlich gab es eine Kopie.
In [566]: x.T.reshape(2,3)
Out[566]:
array([[0, 3, 1],
[4, 2, 5]])
die Reihenfolge der Werte nach dem Ravel ähnlich sieht, und mehr offensichtlich so nach reshape.
In [567]: x.ravel(order='F')
Out[567]: array([0, 3, 1, 4, 2, 5])
In [568]: x.ravel(order='F').reshape(2,3)
Out[568]:
array([[0, 3, 1],
[4, 2, 5]])
OK Ich sehe, so scheint es wirklich wie es ist egal, was ich wähle. Vielen Dank! –
Interessanterweise zeigte das Timing, dass np.reshape (v.T, reshape_tuple) viel schneller ist als np.reshape (v.ravel (order = 'F'), reshape_tuple). –
Vielleicht ist das 'reshape_tuple' so, dass' np.reshape (v.T, reshape_tuple) 'nicht kopiert werden muss. Das heißt, die neue Form ist mit der transponierten Form kompatibel. Ich würde das '__array_interface__' überprüfen. – hpaulj