Skip to content

NumPy: Mit astype() ndarray in einen bestimmten dtype umwandeln

Python

Das NumPy-Array ndarray hat einen Datentyp dtype, der beim Erstellen des ndarray-Objekts mit np.array() angegeben werden kann. Sie können es auch mit der Methode astype() in einen anderen Typ konvertieren.

Grundsätzlich WIRD ein dtype für ein ndarray-Objekt festgelegt, und alle Elemente sind vom gleichen Datentyp.

Dieser Artikel hat folgenden Inhalt.

  • Liste der einfachen Datentypen (dtype) in NumPy
  • Wertebereich (Mindest- und Höchstwerte) für numerische Typen
  • Die Anzahl der Zeichen in einer Zeichenfolge
  • Objekt: Gespeicherter Zeiger auf Python-Objekte
  • Cast-Datentyp (dtype) mit astype()
  • Rundung beim Gießen von float nach int
  • Implizite Typkonvertierungen

Siehe den folgenden Artikel für die Datentypen dtype und astype() in Pandas.

Liste der einfachen Datentypen (dtype) in NumPy

Das Folgende ist eine Liste der einfachen Datentypen dtype in NumPy. Der Wertebereich (= Minimal- und Maximalwert), der von jedem Typ von Ganzzahl und Fließkommazahl angenommen Werden can, WIRD später beschrieben.

dtyp Zeichencode Benennung
int8 i1 8-Bit-Ganzzahl mit Vorzeichen
int16 i2 16-Bit-Ganzzahl mit Vorzeichen
int32 i4 32-Bit-Ganzzahl mit Vorzeichen
int64 i8 64-Bit-Ganzzahl mit Vorzeichen
uint8 u1 8-Bit-Ganzzahl ohne Vorzeichen
uint16 u2 16-Bit-Ganzzahl ohne Vorzeichen
uint32 u4 32-Bit-Ganzzahl ohne Vorzeichen
uint64 u8 64-Bit-Ganzzahl ohne Vorzeichen
float16 f2 16-Bit-Gleitkommazahl
float32 f4 32-Bit-Gleitkommazahl
float64 f8 64-Bit-Gleitkommazahl
float128 F 16 128-Bit-Gleitkommazahl
komplex64 c8 Komplexe 64-Bit-Gleitkommazahl
Komplex128 c16 Komplexe 128-Bit-Gleitkommazahl
Komplex256 c32 Komplexe 256-Bit-Gleitkommazahl
bool ? Boolean (Wahr oder Falsch)
Unicode U Unicode-String
Objekt Ö Python-Objekte

Die Zahlen von dtype sind in Bit und die Zahlen von Zeichencode sind in Byte. Beachten Sie, dass die Nummern auch für den gleichen Typ unterschiedlich sind.

Der Zeichencode für den Typ bool, ? bedeutet nicht unbekannt, sondern wörtlich ? zugeordnet ist.

Wenn der Datentyp dtype beispielsweise als Argument verschiedener Methoden und Funktionen angegeben WIRD, kann SIE für int64 Folgendes verwenden:

import numpy as np

a = np.array([1, 2, 3], dtype=np.int64)
print(a.dtype)
# int64

a = np.array([1, 2, 3], dtype='int64')
print(a.dtype)
# int64

a = np.array([1, 2, 3], dtype='i8')
print(a.dtype)
# int64

Es kann auch als ein in Python integrierter Typ wie int, float oder str angegeben werden.

In diesem Fall wird er in den entsprechenden Typ umgewandelt. Beispiele in Python3, 64-Bit-Umgebung sind wie folgt. uint ist kein Python-Typ, WIRD aber der Einfachheit halber zusammen aufgelistet.

Python-Typ Beispiel für äquivalenten dtype
int int64
schweben float64
Str Unicode
(nicht) uint64

Als Argumente sind sowohl int als auch der String ‚int‘ erlaubt; Für uint ist nur die Zeichenfolge „uint“ zulässig, die kein Python-Typ ist.

print(int is np.int)
# True

a = np.array([1, 2, 3], dtype=int)
print(a.dtype)
# int64

a = np.array([1, 2, 3], dtype='int')
print(a.dtype)
# int64

Wertebereich (Mindest- und Höchstwerte) für numerische Typen

Sie können np.iinfo() und np.fininfo() verwenden, um den Bereich möglicher Werte für jeden Datentyp von Integer int, uint und Fließkommazahl Float zu überprüfen.

np.iinfo()

Verwenden Sie np.iinfo() für ganze Zahlen int und uint.

Der Typ numpy.iinfo WIRD zurückgegeben, jedoch ein Typobjekt als Argument angegeben WIRD.

SIE kann print() verwenden, um Eine Zusammenfassung und Max- und Min-Attribute auszudrucken, um die Maximal- und Minimalwerte zu erhalten.

ii64 = np.iinfo(np.int64)
print(type(ii64))
# <class 'numpy.iinfo'>

print(ii64)
# Machine parameters for int64
# ---------------------------------------------------------------
# min = -9223372036854775808
# max = 9223372036854775807
# ---------------------------------------------------------------
# 

print(ii64.max)
# 9223372036854775807

print(type(ii64.max))
# <class 'int'>

print(ii64.min)
# -9223372036854775808

print(ii64.bits)
# 64

Sie können auch einen String angeben, der den dtype als Argument darstellt.

print(np.iinfo('int16'))
# Machine parameters for int16
# ---------------------------------------------------------------
# min = -32768
# max = 32767
# ---------------------------------------------------------------
# 

print(np.iinfo('i4'))
# Machine parameters for int32
# ---------------------------------------------------------------
# min = -2147483648
# max = 2147483647
# ---------------------------------------------------------------
# 

print(np.iinfo(int))
# Machine parameters for int64
# ---------------------------------------------------------------
# min = -9223372036854775808
# max = 9223372036854775807
# ---------------------------------------------------------------
# 

print(np.iinfo('uint64'))
# Machine parameters for uint64
# ---------------------------------------------------------------
# min = 0
# max = 18446744073709551615
# ---------------------------------------------------------------
# 

Der Wert selbst kann auch als Argument angegeben werden.

i = 100
print(type(i))
# <class 'int'>

print(np.iinfo(i))
# Machine parameters for int64
# ---------------------------------------------------------------
# min = -9223372036854775808
# max = 9223372036854775807
# ---------------------------------------------------------------
# 

ui = np.uint8(100)
print(type(ui))
# <class 'numpy.uint8'>

print(np.iinfo(ui))
# Machine parameters for uint8
# ---------------------------------------------------------------
# min = 0
# max = 255
# ---------------------------------------------------------------
# 

NumPy-Array ndarray ist nicht zulässig. Rufen Sie den Datentyp mit dem dtype-Attribut ab oder rufen Sie ein Element ab und geben Sie es an.

a = np.array([1, 2, 3], dtype=np.int8)
print(type(a))
# <class 'numpy.ndarray'>

# print(np.iinfo(a))
# ValueError: Invalid integer data type 'O'.

print(np.iinfo(a.dtype))
# Machine parameters for int8
# ---------------------------------------------------------------
# min = -128
# max = 127
# ---------------------------------------------------------------
# 

print(np.iinfo(a[0]))
# Machine parameters for int8
# ---------------------------------------------------------------
# min = -128
# max = 127
# ---------------------------------------------------------------
# 

np.finfo()

Verwenden Sie np.fininfo() für Fließkommazahlen float.

Die Verwendung ist die gleiche wie bei np.iinfo().

Das Argument kann ein Typobjekt (np.float64), ein String (‚float64‘, ‚f8‘) oder ein Wert (0.1) sein.

fi64 = np.finfo(np.float64)
print(type(fi64))
# <class 'numpy.finfo'>

print(fi64)
# Machine parameters for float64
# ---------------------------------------------------------------
# precision =  15   resolution = 1.0000000000000001e-15
# machep =    -52   eps =        2.2204460492503131e-16
# negep =     -53   epsneg =     1.1102230246251565e-16
# minexp =  -1022   tiny =       2.2250738585072014e-308
# maxexp =   1024   max =        1.7976931348623157e+308
# nexp =       11   min =        -max
# ---------------------------------------------------------------
# 

print(fi64.max)
# 1.7976931348623157e+308

print(type(fi64.max))
# <class 'numpy.float64'>

print(fi64.min)
# -1.7976931348623157e+308

print(fi64.eps)
# 2.220446049250313e-16

print(fi64.bits)
# 64

print(fi64.iexp)
# 11

print(fi64.nmant)
# 52

Wie im obigen Beispiel gezeigt, kann SIE Epsilon mit eps, Anzahl der Bits in Exponential- und Mantissenteilen mit iexp und nmant usw. erhalten.

Weitere Informationen finden Sie in der offiziellen Dokumentation oben.

Die Anzahl der Zeichen in einer Zeichenfolge

Wenn Sie str oder Unicode verwenden, ist dtype wie <U1.

a_str = np.array([1, 2, 3], dtype=str)
print(a_str)
print(a_str.dtype)
# ['1' '2' '3']
# <U1

< und > gibt es Little-Endian bzw. Big-Endian an.

Die Zahl am Ende gibt die Anzahl der Zeichen an. Es ist die maximale Anzahl von Zeichen unter allen Elementen, wenn dtype wie in diesem Beispiel als str oder unicode in np.array() angegeben ist.

Da jedem Element nur diese Zeichenanzahl zugewiesen WIRD, Werden Strings mit mehr als dieser Zeichenanzahl abgeschnitten.

Sie können vorher einen Typ mit einer ausreichenden Anzahl von Zeichen angeben.

a_str[0] = 'abcde'
print(a_str)
# ['a' '2' '3']

a_str10 = np.array([1, 2, 3], dtype='U10')
print(a_str10.dtype)
# <U10

a_str10[0] = 'abcde'
print(a_str10)
# ['abcde' '2' '3']

Objekt: Gespeicherter Zeiger auf Python-Objekte

Der Objekttyp ist ein spezieller Datentyp, der Zeiger auf Python-Objekte speichert.

Da jede Datenentität jedes Elements seinem eigenen Speicherbereich zuweist, ist es möglich, (Zeiger auf) Datentypen in einem einzigen Array zu haben.

a_object = np.array([1, 0.1, 'one'], dtype=object)
print(a_object)
print(a_object.dtype)
# [1 0.1 'one']
# object

print(type(a_object[0]))
print(type(a_object[1]))
print(type(a_object[2]))
# <class 'int'>
# <class 'float'>
# <class 'str'>

Sie können auch die Anzahl der Zeichen ändern.

a_object[2] = 'oneONE'
print(a_object)
# [1 0.1 'oneONE']

Beachten Sie, dass solche Arrays mit mehreren Typen auch mit Pythons eingebautem Listentyp realisiert werden können.

list und numpy.ndarray haben unterschiedliche Verhaltensweisen für Operatoren. Im Fall von ndarray ist es einfach, Operationen an jedem Element durchzuführen.

l = [1, 0.1, 'oneONE']
print(type(l[0]))
print(type(l[1]))
print(type(l[2]))
# <class 'int'>
# <class 'float'>
# <class 'str'>

print(a_object * 2)
# [2 0.2 'oneONEoneONE']

print(l * 2)
# [1, 0.1, 'oneONE', 1, 0.1, 'oneONE']

Cast-Datentyp (dtype) mit astype()

Die Methode astype() von numpy.ndarray kann den Datentyp dtype konvertieren.

Ein neues ndarray wird mit einem neuen dtype erstellt, und das ursprüngliche ndarray wird nicht geändert.

import numpy as np

a = np.array([1, 2, 3])
print(a)
print(a.dtype)
# [1 2 3]
# int64

a_float = a.astype(np.float32)
print(a_float)
print(a_float.dtype)
# [1. 2. 3.]
# float32

print(a)
print(a.dtype)
# [1 2 3]
# int64

Wie oben erwähnt, kann dtype auf verschiedene Arten angegeben werden.

a_float = a.astype(float)
print(a_float)
print(a_float.dtype)
# [1. 2. 3.]
# float64

a_str = a.astype('str')
print(a_str)
print(a_str.dtype)
# ['1' '2' '3']
# <U21

a_int = a.astype('int32')
print(a_int)
print(a_int.dtype)
# [1 2 3]
# int32

Rundung beim Gießen von float nach int

Beim Gießen von float nach int WIRD der Dezimalpunkt abgeschnitten und auf 0 gerundet.

a = np.arange(50).reshape((5, 10)) / 10 - 2
print(a)
print(a.dtype)
# [[-2.  -1.9 -1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1]
#  [-1.  -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1]
#  [ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9]
#  [ 1.   1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9]
#  [ 2.   2.1  2.2  2.3  2.4  2.5  2.6  2.7  2.8  2.9]]
# float64

a_int = a.astype('int64')
print(a_int)
print(a_int.dtype)
# [[-2 -1 -1 -1 -1 -1 -1 -1 -1 -1]
#  [-1  0  0  0  0  0  0  0  0  0]
#  [ 0  0  0  0  0  0  0  0  0  0]
#  [ 1  1  1  1  1  1  1  1  1  1]
#  [ 2  2  2  2  2  2  2  2  2  2]]
# int64

np.round() und np.around() runden auf den nächsten geraden Wert. 0,5 kann statt auf 1 auf 0 gerundet werden.

print(np.round(a).astype(int))
# [[-2 -2 -2 -2 -2 -2 -1 -1 -1 -1]
#  [-1 -1 -1 -1 -1  0  0  0  0  0]
#  [ 0  0  0  0  0  0  1  1  1  1]
#  [ 1  1  1  1  1  2  2  2  2  2]
#  [ 2  2  2  2  2  2  3  3  3  3]]

Wenn Sie die folgende Funktion definieren, wird 0,5 auf 1 gerundet.

my_round_int = lambda x: np.round((x * 2 + 1) // 2)

print(my_round_int(a).astype(int))
# [[-2 -2 -2 -2 -2 -1 -1 -1 -1 -1]
#  [-1 -1 -1 -1 -1  0  0  0  0  0]
#  [ 0  0  0  0  0  1  1  1  1  1]
#  [ 1  1  1  1  1  2  2  2  2  2]
#  [ 2  2  2  2  2  3  3  3  3  3]]

Die obige Funktion rundet -0,5 auf 0. Wenn Sie -0,5 auf -1 runden möchten, sollte die Funktion wie folgt aussehen.

def my_round(x, digit=0):
    p = 10 ** digit
    s = np.copysign(1, x)
    return (s * x * p * 2 + 1) // 2 / p * s

print(my_round(a).astype(int))
# [[-2 -2 -2 -2 -2 -2 -1 -1 -1 -1]
#  [-1 -1 -1 -1 -1 -1  0  0  0  0]
#  [ 0  0  0  0  0  1  1  1  1  1]
#  [ 1  1  1  1  1  2  2  2  2  2]
#  [ 2  2  2  2  2  3  3  3  3  3]]

Implizite Typkonvertierungen

Zusätzlich zur expliziten Typkonvertierung durch astype() kann eine implizite Typkonvertierung durch einige Operationen durchgeführt werden.

ZB gibt die Division durch den /-Operator eine Fließkommazahl Float zurück.

a = np.array([1, 2, 3])
print(a)
print(a.dtype)
# [1 2 3]
# int64

print((a / 1).dtype)
# float64

print((a / 1.0).dtype)
# float64

Für +, -, *, // und ** ist das Ergebnis int, wenn alle zwischen int liegen, und float, wenn sie float enthalten.

print((a + 1).dtype)
# int64

print((a + 1.0).dtype)
# float64

print((a - 1).dtype)
# int64

print((a - 1.0).dtype)
# float64

print((a * 1).dtype)
# int64

print((a * 1.0).dtype)
# float64

print((a // 1).dtype)
# int64

print((a // 1.0).dtype)
# float64

print((a ** 1).dtype)
# int64

print((a ** 1.0).dtype)
# float64

Dasselbe gilt für Operationen zwischen numpy.ndarray.

Auch zwischen int WIRD der Typ konvertiert, wenn die Anzahl der Bits unterschiedlich ist.

ones_int16 = np.ones(3, np.int16)
print(ones_int16)
# [1 1 1]

ones_int32 = np.ones(3, np.int32)
print(ones_int32)
# [1 1 1]

print((ones_int16 + ones_int32).dtype)
# int32

Wie in diesem Beispiel können Sie davon ausgehen, dass der Datentyp grundsätzlich auf den mit der größeren Datenmenge konvertiert wird.

In einigen Fällen kann sich der Typ jedoch von den ursprünglichen numpy.ndarray-Typen unterscheiden. Wenn die Anzahl der Bits wichtig ist, ist es besser, sie explizit mit astype() in den gewünschten Typ umzuwandeln.

ones_float16 = np.ones(3, np.float16)
print(ones_float16)
# [1. 1. 1.]

print((ones_int16 + ones_float16).dtype)
# float32

Beachten Sie, dass der Typ von numpy.ndarray nicht konvertiert wird, wenn einem Element ein Wert zugewiesen wird.

Wenn Sie beispielsweise einer Ganzzahl numpy.ndarray einen Gleitkommawert zuweisen, ist der Datentyp von numpy.ndarray immer noch int. Der zugewiesene Wert wird nach dem Komma abgeschnitten.

ones_int16[0] = 10.9
print(ones_int16)
# [10  1  1]

print(ones_int16.dtype)
# int16