2010-10-07 23 views
90

Come si aggiungono le righe a un array numpy?Numpy - aggiungi riga all'array

Ho un array A:

A = array([[0, 1, 2], [0, 2, 0]]) 

desidero aggiungere righe a questa matrice da un'altra matrice X se il primo elemento di ciascuna riga X soddisfa una condizione specifica.

Gli array di Numpy non hanno un metodo "append" come quello delle liste, o così sembra.

Se A e X sono liste mi limito faccio:

for i in X: 
    if i[0] < 3: 
     A.append(i) 

Esiste un numpythonic modo di fare l'equivalente?

Grazie, S ;-)

+0

Vedere anche http://stackoverflow.com/questions/8486294/how-to-add-an-extra-column-to-an-numpy-array –

risposta

77

Qual è X? Se si tratta di un array 2D, come è possibile confrontare la sua riga con un numero: i < 3?

EDIT dopo il commento di OP:

A = array([[0, 1, 2], [0, 2, 0]]) 
X = array([[0, 1, 2], [1, 2, 0], [2, 1, 2], [3, 2, 0]]) 

aggiungi al A tutte le righe dalla X dove il primo elemento < 3:

A = vstack((A, X[X[:,0] < 3])) 

# returns: 
array([[0, 1, 2], 
     [0, 2, 0], 
     [0, 1, 2], 
     [1, 2, 0], 
     [2, 1, 2]]) 
+1

Scusa, buon punto! Assumi un array 2D di cui il primo elemento di ogni riga deve soddisfare una condizione. Lo modificherò. Grazie, S ;-) –

+2

@ DarrenJ.Fitzpatrick Tenete presente che, facendo questo tipo di manipolazione, si lavora contro il buon lavoro che Numpy fa nella pre-allocazione della memoria per l'array esistente 'A'. Chiaramente per piccoli problemi come in questa risposta, questo non è un problema, ma può essere più problematico per i dati di grandi dimensioni. – dtlussier

107

ben u può fare questo:

newrow = [1,2,3] 
    A = numpy.vstack([A, newrow]) 
+6

Funziona, ma ... i documenti dicono che vstack ora è deprecato. (Probabilmente non c'è modo di tornare indietro quando è stata scritta questa risposta). Qual è il modo non deprecato di farlo al giorno d'oggi? – Kris

7

È può anche fare questo:

newrow = [1,2,3] 
A = numpy.concatenate((A,newrow)) 
+0

hmmm. quando ho provato questo, è stato aggiunto alla fine di A, piuttosto che aggiungere una nuova riga come OP richiesto. –

+9

probabilmente 'np.concatenate ((A, newrow), axis = 0)' –

+1

A partire dalla versione numpy '1.12.1' (e in Python 3), sembra che il tentativo di concatenare un vettore ad una matrice eleva' ValueError: tutti gli array di input devono avere lo stesso numero di dimensioni ». Sembra che desideri che il vettore venga riscritto esplicitamente in un vettore di colonna o di riga prima che sia disposto a concatenarlo. – MRule

2

Se è possibile eseguire la costruzione in una singola operazione, allora qualcosa come la risposta di vstack-with-fancy-indexing è un buon approccio. Ma se le tue condizioni sono più complicate o le tue file arrivano al volo, potresti voler far crescere l'array. In realtà il modo numpythonic a fare qualcosa di simile - crescere in modo dinamico una matrice - è quello di crescere in modo dinamico un elenco:

A = np.array([[1,2,3],[4,5,6]]) 
Alist = [r for r in A] 
for i in range(100): 
    newrow = np.arange(3)+i 
    if i%5: 
     Alist.append(newrow) 
A = np.array(Alist) 
del Alist 

liste sono altamente ottimizzati per questo tipo di modello di accesso; non si dispone di un'indicizzazione multidimensionale numpy conveniente mentre si trova in forma di elenco, ma fino a quando si sta aggiungendo è difficile fare meglio di un elenco di matrici di righe.

1

È possibile utilizzare numpy.append() per aggiungere una riga all'array numpty e rimodellare in seguito una matrice.

import numpy as np 
a = np.array([1,2]) 
a = np.append(a, [3,4]) 
print a 
# [1,2,3,4] 
# in your example 
A = [1,2] 
for row in X: 
    A = np.append(A, row) 
6

Poiché questa domanda è stato 7 anni prima, nella sua ultima versione, che sto utilizzando è NumPy versione 1.13, e python3, sto facendo la stessa cosa con l'aggiunta di una riga a una matrice, ricordatevi di mettere un doppia parentesi al secondo argomento, altrimenti aumenterà l'errore di dimensione.stesso uso in np.r_

np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0) 
>> array([[1, 2, 3], 
      [4, 5, 6], 
      [7, 8, 9]]) 

Solo per qualcuno tirammo fuori, se si desidera aggiungere una colonna,

array = np.c_[A,np.zeros(#A's row size)]

0

Io uso 'np.vstack' che è più veloce, EX:

import numpy as np 

input_array=np.array([1,2,3]) 
new_row= np.array([4,5,6]) 

new_array=np.vstack([input_array, new_row]) 
0

Se non sono necessari calcoli dopo ogni riga, è molto più rapido aggiungere righe in python, quindi convertire in numpy. Qui sono i tempi test utilizzando Python 3.6 vs NumPy 1.14, l'aggiunta di 100 righe, uno alla volta:

import numpy as py 
from time import perf_counter, sleep 

def time_it(): 
    # Compare performance of two methods for adding rows to numpy array 
    py_array = [[0, 1, 2], [0, 2, 0]] 
    py_row = [4, 5, 6] 
    numpy_array = np.array(py_array) 
    numpy_row = np.array([4,5,6]) 
    n_loops = 100 

    start_clock = perf_counter() 
    for count in range(0, n_loops): 
     numpy_array = np.vstack([numpy_array, numpy_row]) # 5.8 micros 
    duration = perf_counter() - start_clock 
    print('numpy 1.14 takes {:.3f} micros per row'.format(duration * 1e6/n_loops)) 

    start_clock = perf_counter() 
    for count in range(0, n_loops): 
     py_array.append(py_row) # .15 micros 
    numpy_array = np.array(py_array) # 43.9 micros  
    duration = perf_counter() - start_clock 
    print('python 3.6 takes {:.3f} micros per row'.format(duration * 1e6/n_loops)) 
    sleep(15) 

#time_it() prints: 

numpy 1.14 takes 5.971 micros per row 
python 3.6 takes 0.694 micros per row 

Quindi, la soluzione semplice alla domanda iniziale, da sette anni fa, è quello di utilizzare vstack() per aggiungi una nuova riga dopo aver convertito la riga in una matrice numpy. Ma una soluzione più realistica dovrebbe prendere in considerazione le scarse prestazioni di vstack in tali circostanze. Se non è necessario eseguire l'analisi dei dati sull'array dopo ogni aggiunta, è meglio memorizzare le nuove righe in un elenco python di righe (un elenco di elenchi, in realtà) e aggiungerle come gruppo all'array numpy usando vstack() prima di fare qualsiasi analisi dei dati.

Problemi correlati