import numpy as NP
my_data = NP.random.random_integers(0, 9, 9).reshape(3, 3)
new_col = NP.array((5, 5, 5)).reshape(3, 1)
res = NP.append(my_data, new_col, axis=1)
il secondo frammento (hstack) funzionerà se si aggiunge un'altra linea, ad esempio,
my_data = NP.random.random_integers(0, 9, 16).reshape(4, 4)
# the line to add--does not depend on array dimensions
new_col = NP.zeros_like(my_data[:,-1]).reshape(-1, 1)
res = NP.hstack((my_data, new_col))
hstack
g È lo stesso risultato di concatenate((my_data, new_col), axis=1)
, non sono sicuro di come si confrontano le prestazioni.
Mentre questa è la risposta più diretta alla tua domanda, devo dire che il ciclo attraverso una fonte di dati per popolare una destinazione tramite accoda, mentre bene in Python, non è idiomatica NumPy. Ecco perché:
inizializzare una matrice NumPy è relativamente costoso, e con questo modello pitone convenzionale, si incorrere quel costo, più o meno, ad ogni iterazione del ciclo (cioè, ogni accoda a una matrice NumPy è approssimativamente come inizializzazione un nuovo array con una dimensione diversa).
Per tale motivo, il modello comune in NumPy per iterativa aggiunta di colonne di una matrice 2D è inizializzare una matrice di destinazione vuoto volta (o pre-allocare un singolo array 2D NumPy aventi tutte le colonne vuote) la successivamente popolano le colonne vuote impostando il desiderato colonna-saggio offset() - molto più facile da mostrare che da spiegare:
>>> # initialize your skeleton array using 'empty' for lowest-memory footprint
>>> M = NP.empty(shape=(10, 5), dtype=float)
>>> # create a small function to mimic step-wise populating this empty 2D array:
>>> fnx = lambda v : NP.random.randint(0, 10, v)
popolano matrice NumPy come nel PO, tranne ogni iterazione appena ri-imposta i valori di M a successivi offset di colonna
>>> for index, itm in enumerate(range(5)):
M[:,index] = fnx(10)
>>> M
array([[ 1., 7., 0., 8., 7.],
[ 9., 0., 6., 9., 4.],
[ 2., 3., 6., 3., 4.],
[ 3., 4., 1., 0., 5.],
[ 2., 3., 5., 3., 0.],
[ 4., 6., 5., 6., 2.],
[ 0., 6., 1., 6., 8.],
[ 3., 8., 0., 8., 0.],
[ 5., 2., 5., 0., 1.],
[ 0., 6., 5., 9., 1.]])
naturalmente se non si sa in anticipo che cosa dimensioni l'array dovrebbe essere basta creare una molto più grande del necessario e tagliare le porzioni 'Libero' quando hai finito popolato
>>> M[:3,:3]
array([[ 9., 3., 1.],
[ 9., 6., 8.],
[ 9., 7., 5.]])
Post molto utile per un principiante intorpidito. Domanda veloce: v'è alcuna ragione per cui si utilizza 'per l'indice, ITM in enumerate (range (5)):' e non solo, per esempio, 'per x nella gamma (5):' visto come index e itm hanno lo stesso valore e ne viene usato solo uno. –
@ JohnBarça grazie per il feedback. Potresti avere ragione nel ritenere che i dettagli del mio frammento di codice avrebbero dovuto essere scelti con maggiore attenzione, ovvero, nel mio esempio, il valore di "indice" ad ogni iterazione è in effetti uguale al valore della variabile di ciclo. Questo è un artefatto però - i valori di queste due variabili probabilmente non saranno uguali nella pratica (ad esempio, l'iterabile è una lista contenente valori da passare a una funzione che crea gli array 1D che vengono poi "inseriti" nell'array di destinazione). – doug