HOWTO · NumPy

Come ottenere una colonna da un array NumPy

Seleziona una o più colonne da un array NumPy bidimensionale, conserva la forma richiesta, filtra le righe e scegli tra una vista e una copia.

In questa pagina

Per selezionare una colonna da un array NumPy bidimensionale, usa array[:, column_index]. I due punti selezionano tutte le righe, mentre l’intero seleziona una colonna con indice a partire da zero. Ad esempio, data[:, 1] restituisce la seconda colonna come array monodimensionale. Usa invece data[:, 1:2] quando il codice successivo richiede un risultato bidimensionale con forma (rows, 1).

Selezionare una colonna e controllarne la forma

NumPy indicizza un array 2D come array[row_selection, column_selection]. Omettere la virgola cambia l’operazione: data[:][1] crea prima uno slice completo e poi seleziona la riga 1, quindi non seleziona la colonna 1.

L’esempio seguente copre i casi comuni di selezione delle colonne in un unico programma riproducibile:

import numpy as np

data = np.array([[10, 11, 12], [20, 21, 22], [30, 31, 32]])

second = data[:, 1]
second_2d = data[:, 1:2]
adjacent = data[:, :2]
reordered = data[:, [2, 0]]
taken = np.take(data, [0, 2], axis=1)
filtered = data[data[:, 0] >= 20, 2]

print("second:", second, second.shape)
print("second_2d:\n", second_2d, second_2d.shape)
print("adjacent:\n", adjacent)
print("reordered:\n", reordered)
print("taken:\n", taken)
print("filtered:", filtered)

view = data[:, 1]
copy = data[:, 1].copy()
view[0] = 99
print("data after view edit:\n", data)
print("copy:", copy)

Risultato:

second: [11 21 31] (3,)
second_2d:
 [[11]
 [21]
 [31]] (3, 1)
adjacent:
 [[10 11]
 [20 21]
 [30 31]]
reordered:
 [[12 10]
 [22 20]
 [32 30]]
taken:
 [[10 12]
 [20 22]
 [30 32]]
filtered: [22 32]
data after view edit:
 [[10 99 12]
 [20 21 22]
 [30 31 32]]
copy: [11 21 31]

Un indice di colonna intero rimuove quell’asse, il che spiega la forma (3,) di second. Uno slice con un solo elemento mantiene l’asse, producendo la forma (3, 1) di second_2d. Questa distinzione è importante quando un’API richiede un input simile a una matrice invece di un vettore piatto.

Selezionare più colonne

Usa uno slice come data[:, :2] per le colonne adiacenti. Lo slicing esprime un intervallo continuo e in genere produce una vista. Per colonne non adiacenti o un ordine personalizzato, fornisci una lista di indici: data[:, [2, 0]]. Questa è un’indicizzazione avanzata e produce una copia anziché una vista.

Una lista di indici mantiene sempre l’asse delle colonne. Pertanto, data[:, [1]] ha forma (3, 1), mentre data[:, 1] ha forma (3,). Una lista può anche ripetere una colonna o cambiarne la posizione, quindi convalida gli indici forniti dinamicamente se duplicati o ordinamenti inattesi potrebbero creare problemi. Usa uno slice quando le colonne formano un intervallo semplice e una lista di indici quando la selezione stessa è una sequenza.

np.take è un’alternativa che rende esplicito l’asse. np.take(data, [0, 2], axis=1) seleziona le colonne 0 e 2; axis=1 è essenziale perché le colonne occupano il secondo asse. È particolarmente utile quando l’asse o gli indici sono memorizzati in variabili.

Filtrare le righe prima di leggere una colonna

Una condizione booleana identifica normalmente le righe, non le colonne. Crea la maschera delle righe da una colonna, quindi inserisci la colonna di output richiesta dopo la virgola. Nell’esempio, data[:, 0] >= 20 mantiene le ultime due righe e data[data[:, 0] >= 20, 2] restituisce [22 32] dalla colonna 2. La lunghezza della maschera deve corrispondere al numero di righe.

Decidere se serve una vista o una copia

Secondo le regole di indicizzazione di NumPy, lo slicing di base restituisce una vista quando possibile, mentre l’indicizzazione avanzata restituisce una copia. Di conseguenza, l’assegnazione tramite view = data[:, 1] può modificare data, come dimostra il valore 99 nell’output. Chiama .copy() quando la colonna estratta deve essere indipendente. I valori copiati rimangono [11 21 31] dopo che la vista modifica l’array di origine.

Queste viste mantengono inoltre raggiungibile la memoria dell’array di base. Copia una colonna piccola se conservare un grande array di origine sprecherebbe memoria dopo che il resto dell’array non è più necessario.

Controllare le dimensioni e i limiti delle colonne

Queste espressioni presuppongono un array 2D. Un array 1D non ha un asse delle colonne, quindi array[:, 0] genera un errore di indicizzazione. Controlla array.ndim == 2 quando la forma dell’input è incerta. Per un array 2D, gli indici di colonna non negativi validi vanno da 0 a array.shape[1] - 1; un indice esterno a questo intervallo genera IndexError. Anche gli indici negativi sono validi entro i limiti, quindi array[:, -1] seleziona l’ultima colonna.