
L’array NumPy ndarray ha un tipo di dati dtype, che può essere specificato durante la creazione di un oggetto ndarray con np.array(). Puoi anche convertirlo in un altro tipo con il metodo astype().
Fondamentalmente, un dtype è impostato per un oggetto ndarray e tutti gli elementi sono dello stesso tipo di dati.
In questo articolo vengono descritti i seguenti contenuti.
- Elenco dei tipi di dati di base (dtype) in NumPy
- Intervallo di valori (valori minimi e massimi) per i tipi numerici
- Il numero di caratteri in una stringa
- oggetto: memorizzati i puntatori agli oggetti Python
- Trasmetti il tipo di dati (dtype) con astype()
- Arrotondamento quando si lancia da float a int
- Conversioni di tipo implicito
Vedere l’articolo seguente per i tipi di dati dtype e astype() nei panda.
Elenco dei tipi di dati di base (dtype) in NumPy
Di seguito è riportato un elenco di tipi di dati di base dtype in NumPy. L’intervallo di valori (= valori minimo e massimo) che può essere assunto da ciascun tipo di numero intero e in virgola mobile è in seguito.
tipo d | codice carattere | descrizione |
---|---|---|
int8 | i1 | Intero con segno a 8 bit |
int16 | i2 | Intero con segno a 16 bit |
int32 | i4 | Intero con segno a 32 bit |
int64 | i8 | Intero con segno a 64 bit |
uint8 | u1 | Intero senza segno a 8 bit |
uint16 | u2 | Intero senza segno a 16 bit |
uint32 | u4 | Intero senza segno a 32 bit |
uint64 | u8 | Intero senza segno a 64 bit |
galleggiante16 | f2 | Numero a virgola mobile a 16 bit |
galleggiante32 | f4 | Numero a virgola mobile a 32 bit |
galleggiante64 | f8 | Numero a virgola mobile a 64 bit |
galleggiante128 | f16 | Numero a virgola mobile a 128 bit |
complesso64 | c8 | Numero a virgola mobile complesso a 64 bit |
complesso128 | c16 | Numero a virgola mobile complesso a 128 bit |
complesso256 | c32 | Numero a virgola mobile complesso a 256 bit |
bollo | ? | Booleano (vero o falso) |
unicode | tu | Stringa Unicode |
oggetto | o | Oggetti Python |
I numeri di dtype sono in bit ei numeri di codice carattere sono in byte. Si noti che i numeri sono diversi anche per lo stesso tipo.
Il codice del carattere per il tipo bool, ? non significa sconosciuto, ma letteralmente ? è assegnato.
Quando il tipo di dati dtype viene specificato come argomento di vari metodi e funzioni, ad esempio, è possibile utilizzare uno dei seguenti per int64:
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
Può anche essere specificato come tipo integrato in Python come int, float o str.
In questo caso, viene convertito nell’equivalente dtype. Esempi in Python3, ambiente a 64 bit sono i seguenti. uint non è un tipo Python, ma è elencato insieme per comodità.
Tipo Python | Esempio di dtype equivalente |
---|---|
int | int64 |
galleggiante | galleggiante64 |
str | unicode |
(uint) | uint64 |
Sia int che la stringa ‘int’ sono consentiti come argomenti; solo la stringa ‘uint’ è consentita per uint, che non è un tipo Python.
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
Intervallo di valori (valori minimi e massimi) per i tipi numerici
È possibile utilizzare np.iinfo() e np.fininfo() per controllare l’intervallo di valori possibili per ciascun tipo di dati di intero int, uint e numero a virgola mobile float.
np.iinfo()
Usa np.iinfo() per gli interi int e uint.
Il tipo numpy.iinfo viene restituito specificando un oggetto di tipo come argomento.
È possibile utilizzare print() per stampare un riepilogo e gli attributi max e min per ottenere i valori massimo e minimo.
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
Puoi anche specificare una stringa che rappresenta il tipo come argomento.
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
# ---------------------------------------------------------------
#
Il valore stesso può anche essere specificato come argomento.
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 non è consentito. Ottieni il tipo di dati con l’attributo dtype o ottieni un elemento e specificalo.
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()
Usa np.fininfo() per i numeri in virgola mobile float.
L’utilizzo è lo stesso di np.iinfo().
L’argomento può essere un oggetto di tipo (np.float64), una stringa (‘float64’, ‘f8’) o un valore (0.1).
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
Come mostrato nell’esempio sopra, puoi ottenere epsilon con eps, numero di bit in parti esponenziali e mantissa con iexp e nmant e così via.
Vedere la documentazione ufficiale sopra per i dettagli.
Il numero di caratteri in una stringa
Se usi str o unicode, dtype è come <U1.
a_str = np.array([1, 2, 3], dtype=str)
print(a_str)
print(a_str.dtype)
# ['1' '2' '3']
# <U1
< e > invece indica little-endian e big-endian.
Il numero alla fine indica il numero di caratteri. È il numero massimo di caratteri tra tutti gli elementi se dtype è specificato come str o unicode in np.array(), come in questo esempio.
Poiché per ogni elemento viene allocato solo questo numero di caratteri, le stringhe con un numero di superiore a questo numero vengono troncate.
È possibile specificare in anticipo un tipo con un numero sufficiente di caratteri.
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']
oggetto: memorizzati i puntatori agli oggetti Python
Il tipo di oggetto è un tipo di dati speciali che memorizza i puntatori agli oggetti Python.
Poiché ogni entità di dati di ogni elemento alloca la propria area di memoria, è possibile avere (puntatori a) dati di più tipi in un singolo array.
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'>
Puoi anche modificare il numero di caratteri.
a_object[2] = 'oneONE'
print(a_object)
# [1 0.1 'oneONE']
Si noti che tali array con più tipi possono essere realizzati anche con il tipo di elenco integrato di Python.
list e numpy.ndarray hanno comportamenti diversi per gli operatori. Nel caso di ndarray, è facile eseguire operazioni su ogni elemento.
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']
Trasmetti il tipo di dati (dtype) con astype()
Il metodo astype() di numpy.ndarray può adottare il tipo di dati dtype.
Viene creato un nuovo ndarray con un nuovo dtype e il ndarray originale non viene modificato.
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
Come accennato in precedenza, dtype può essere specificato in vari modi.
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
Arrotondamento quando si lancia da float a int
Quando si esegue il cast da float a int, il punto decimale viene troncato e arrotondato per difetto.
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() e np.around() arrotonda al valore pari più vicino. 0,5 può essere arrotondato a 0 anziché a 1.
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]]
Se si definisce la funzione seguente, 0,5 viene arrotondato a 1.
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]]
La funzione sopra arrotondare da -0,5 a 0. Se vuoi arrotondare da -0,5 a -1, la funzione dovrebbe essere la seguente.
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]]
Conversioni di tipo implicito
Oltre alla conversione esplicita del tipo tramite astype(), la conversione implicita del tipo può essere eseguita da alcune operazioni.
Ad esempio, la divisione per l’operatore / riporta un numero a virgola mobile float.
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
Per +, -, *, // e **, il risultato è int se sono tutti compresi tra int e float se contengono float.
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
Lo stesso vale per le operazioni tra numpy.ndarray.
Inoltre, anche tra int, se il numero di bit è diverso, il tipo viene convertito.
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
Vieni in questo esempio, puoi presumere che il tipo di dati sia convertito in quello con la quantità maggiore di dati.
Tuttavia, in alcuni casi, il tipo potrebbe essere diverso da qualsiasi numpy.ndarray originale. Se il numero di bit è importante, è meglio convertirlo nel tipo desiderato con astype().
ones_float16 = np.ones(3, np.float16)
print(ones_float16)
# [1. 1. 1.]
print((ones_int16 + ones_float16).dtype)
# float32
Si noti che il tipo di numpy.ndarray non viene convertito quando si assegna un valore a un elemento.
Ad esempio, se si assegna un valore float a un numero intero numpy.ndarray, il tipo di dati di numpy.ndarray è ancora int. Il valore ricevuto viene troncato dopo la virgola.
ones_int16[0] = 10.9
print(ones_int16)
# [10 1 1]
print(ones_int16.dtype)
# int16