Skip to content

NumPy: Hinzufügen neuer Dimensionen zu ndarray (np.newaxis, np.expand_dims)

Python

Sie können einem NumPy-Array ndarray mit np.newaxis, np.expand_dims() und np.reshape() (oder der reshape()-Methode von ndarray) neue Dimensionen hinzufügen (= ein NumPy-Array entkomprimieren).

np.expand_dims() ähnelt Torch.unsqueeze() in PyTorch. Beachten Sie, dass np.unsqueeze() nicht bereitgestellt WIRD.

Dieser Artikel hat folgenden Inhalt.

  • Verwendung von np.newaxis
    • np.newaxis ist keine
    • Fügen Sie neue Dimensionen mit np.newaxis hinzu
    • Steuern Sie die Übertragung mit np.newaxis
  • Fügen Sie eine neue Dimension mit np.expand_dims() hinzu
  • np.reshape()

Sie können die Methode np.reshape() oder reshape() von ndarray verwenden, um nicht nur Bemaßungen hinzuzufügen, sondern auch eine beliebige Form zu ändern.

Sie können np.squeeze() verwenden, um Bemaßungen der Größe 1 zu entfernen.

Verwendung von np.newaxis

np.newaxis ist keine

np.newaxis ist ein Alias ​​für None.

import numpy as np

print(np.newaxis is None)
# True

Es ist nur ein Alias ​​​​gegeben, um es leichter verständlich zu machen. Wenn Sie np.newaxis im Beispielcode unten durch None ersetzen, funktioniert es auf die gleiche Weise.

Fügen Sie neue Dimensionen mit np.newaxis hinzu

Die Verwendung von np.newaxis innerhalb von [] fügt an dieser Position eine neue Dimension der Größe 1 hinzu.

a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
#  [3 4 5]]

print(a.shape)
# (2, 3)

print(a[:, :, np.newaxis])
# [[[0]
#   [1]
#   [2]]
# 
#  [[3]
#   [4]
#   [5]]]

print(a[:, :, np.newaxis].shape)
# (2, 3, 1)
print(a[:, np.newaxis, :])
# [[[0 1 2]]
# 
#  [[3 4 5]]]

print(a[:, np.newaxis, :].shape)
# (2, 1, 3)
print(a[np.newaxis, :, :])
# [[[0 1 2]
#   [3 4 5]]]

print(a[np.newaxis, :, :].shape)
# (1, 2, 3)

Das abschließende : in [] kann weggelassen werden.

print(a[:, np.newaxis])
# [[[0 1 2]]
# 
#  [[3 4 5]]]

print(a[:, np.newaxis].shape)
# (2, 1, 3)
print(a[np.newaxis])
# [[[0 1 2]
#   [3 4 5]]]

print(a[np.newaxis].shape)
# (1, 2, 3)

Konsekutiv : kann durch … ersetzt werden. Wenn Sie der letzten Dimension von ndarray, sterben viele Dimensionen hat, eine neue Dimension hinzufügen möchten, ist es einfacher zu verwenden ….

print(a[..., np.newaxis])
# [[[0]
#   [1]
#   [2]]
# 
#  [[3]
#   [4]
#   [5]]]

print(a[..., np.newaxis].shape)
# (2, 3, 1)

Sie können mehrere np.newaxis gleichzeitig verwenden. Mehrere Dimensionen werden hinzugefügt.

print(a[np.newaxis, :, np.newaxis, :, np.newaxis])
# [[[[[0]
#     [1]
#     [2]]]
# 
# 
#   [[[3]
#     [4]
#     [5]]]]]

print(a[np.newaxis, :, np.newaxis, :, np.newaxis].shape)
# (1, 2, 1, 3, 1)

Das Hinzufügen einer Dimension durch np.newaxis gibt eine Ansicht des ursprünglichen Objekts zurück. Da das ursprüngliche Objekt und das Ansichtsobjekt den Speicher gemeinsam nutzen, ändert das Ändern eines Elements das andere Element.

a_newaxis = a[:, :, np.newaxis]

print(np.shares_memory(a, a_newaxis))
# True

Steuern Sie die Übertragung mit np.newaxis

Beim Betrieb zweier NumPy-Arrays werden diese durch Broadcasting automatisch wieder in die gleiche Form gebracht.

a = np.zeros(27, dtype=np.int).reshape(3, 3, 3)
print(a)
# [[[0 0 0]
#   [0 0 0]
#   [0 0 0]]
# 
#  [[0 0 0]
#   [0 0 0]
#   [0 0 0]]
# 
#  [[0 0 0]
#   [0 0 0]
#   [0 0 0]]]

print(a.shape)
# (3, 3, 3)

b = np.arange(9).reshape(3, 3)
print(b)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

print(b.shape)
# (3, 3)

print(a + b)
# [[[0 1 2]
#   [3 4 5]
#   [6 7 8]]
# 
#  [[0 1 2]
#   [3 4 5]
#   [6 7 8]]
# 
#  [[0 1 2]
#   [3 4 5]
#   [6 7 8]]]

Beim Broadcast wird am Anfang des Arrays eine neue Dimension mit einer kleineren Anzahl von Dimensionen hinzugefügt.

Wenn Sie mit np.newaxis eine neue Dimension am Anfang hinzufügen, ist das Ergebnis so, als ob es automatisch per Broadcasting konvertiert würde.

print(b[np.newaxis, :, :].shape)
# (1, 3, 3)

print(a + b[np.newaxis, :, :])
# [[[0 1 2]
#   [3 4 5]
#   [6 7 8]]
# 
#  [[0 1 2]
#   [3 4 5]
#   [6 7 8]]
# 
#  [[0 1 2]
#   [3 4 5]
#   [6 7 8]]]

Das Ändern der hinzugefügten Position führt zu anderen Erträgen.

print(b[:, np.newaxis, :].shape)
# (3, 1, 3)

print(a + b[:, np.newaxis, :])
# [[[0 1 2]
#   [0 1 2]
#   [0 1 2]]
# 
#  [[3 4 5]
#   [3 4 5]
#   [3 4 5]]
# 
#  [[6 7 8]
#   [6 7 8]
#   [6 7 8]]]
print(b[:, :, np.newaxis].shape)
# (3, 3, 1)

print(a + b[:, :, np.newaxis])
# [[[0 0 0]
#   [1 1 1]
#   [2 2 2]]
# 
#  [[3 3 3]
#   [4 4 4]
#   [5 5 5]]
# 
#  [[6 6 6]
#   [7 7 7]
#   [8 8 8]]]

Wenn Sie beispielsweise Arrays von Farbbildern addieren oder subtrahieren möchten (Form:(height, width, color)) and monochromatic image (shape: (height, width)), it is impossible to broadcast the image as it is, but adding a new dimension at the end of the monochromatic image works well.

Fügen Sie eine neue Dimension mit np.expand_dims() hinzu

Sie können einem NumPy-Array auch mit np.expand_dims() eine neue Dimension hinzufügen.

Geben SIE das ursprüngliche ndarray im ersten Argument a und die Position an, an der die Dimension in der zweiten Argumentachse hinzugefügt werden sollen.

a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
#  [3 4 5]]

print(np.expand_dims(a, 0))
# [[[0 1 2]
#   [3 4 5]]]

print(np.expand_dims(a, 0).shape)
# (1, 2, 3)

Eine neue Bemaßung can SIE an beliebiger Stelle wie folgt einfügen:

print(np.expand_dims(a, 0).shape)
# (1, 2, 3)

print(np.expand_dims(a, 1).shape)
# (2, 1, 3)

print(np.expand_dims(a, 2).shape)
# (2, 3, 1)

Für die zweite Argumentachse kann ein negativer Wert angegeben werden. -1 entspricht der letzten Dimension, und SIE können die Position von hinten angeben.

print(np.expand_dims(a, -1).shape)
# (2, 3, 1)

print(np.expand_dims(a, -2).shape)
# (2, 1, 3)

print(np.expand_dims(a, -3).shape)
# (1, 2, 3)

In NumPy 1.17 verursacht die Angabe eines Werts wie beispielsweise axis > a.ndim oder axis < -a.ndim – 1 im second Argument axis keinen Fehler, und die Dimension wird am Ende oder am Anfang hinzugefügt.

Wie die Warnmeldung besagt, WIRD dies jedoch in Zukunft zu Einem Fehler führen, daher sollten Sie sterben vermeiden.

print(np.expand_dims(a, 3).shape)
# (2, 3, 1)
# 
# /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: Both axis > a.ndim and axis < -a.ndim - 1 are deprecated and will raise an AxisError in the future.
#   """Entry point for launching an IPython kernel.

print(np.expand_dims(a, -4).shape)
# (2, 1, 3)
# 
# /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: Both axis > a.ndim and axis < -a.ndim - 1 are deprecated and will raise an AxisError in the future.
#   """Entry point for launching an IPython kernel.

In der zweiten Argumentachse können nur ganzzahlige Werte angegeben werden. Es ist nicht möglich, mehrere Dimensionen gleichzeitig hinzuzufügen, wenn SIE mehrere Positionen mit einer Liste oder einem Tupel angeben.

# print(np.expand_dims(a, (0, 1)).shape)
# TypeError: '>' not supported between instances of 'tuple' and 'int'

Wie bei np.newaxis gibt np.expand_dims() eine Ansicht zurück.

a_expand_dims = np.expand_dims(a, 0)

print(np.shares_memory(a, a_expand_dims))
# True

Natürlich können Sie das Broadcasting steuern, indem Sie mit np.expand_dims() eine neue Dimension hinzufügen, wie im Beispiel von np.newaxis oben.

np.reshape()

Sie können ndarray mit der Methode np.reshape() oder reshape() von ndarray umformen. Nichts finden Sie im folgenden Artikel.

Wenn Sie reshape() eine Form mit einer neuen Dimension angeben, ist das Ergebnis natürlich dasselbe wie bei Verwendung von np.newaxis oder np.expand_dims().

a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
#  [3 4 5]]

print(a.shape)
# (2, 3)

print(a[np.newaxis])
# [[[0 1 2]
#   [3 4 5]]]

print(a[np.newaxis].shape)
# (1, 2, 3)

print(np.expand_dims(a, 0))
# [[[0 1 2]
#   [3 4 5]]]

print(np.expand_dims(a, 0).shape)
# (1, 2, 3)

print(a.reshape(1, 2, 3))
# [[[0 1 2]
#   [3 4 5]]]

print(a.reshape(1, 2, 3).shape)
# (1, 2, 3)

Wie SIE dem Beispiel entnehmen können, hat die Verwendung von np.newaxis und np.expand_dims() den Vorteil, dass SIE die Größe der ursprünglichen Dimension nicht explizit angeben müssen.

Auch bei reshape() muss man, wenn man am Anfang oder Ende eine Bemaßung hinzufügen möchte, die Größe nicht explizit angeben, dafür man die ursprüngliche Form mit * entpackt.

print(a.reshape(1, *a.shape))
# [[[0 1 2]
#   [3 4 5]]]

print(a.reshape(1, *a.shape).shape)
# (1, 2, 3)