inizializza un array numpy


129

C'è un modo per inizializzare una matrice numpy di una forma e aggiungerla ad essa? Spiegherò di cosa ho bisogno con un esempio di elenco. Se voglio creare un elenco di oggetti generati in un ciclo, posso fare:

a = []
for i in range(5):
    a.append(i)

Voglio fare qualcosa di simile con un array intorpidito. Conosco vstack, concatenare ecc. Tuttavia, sembra che richiedano due array intorpiditi come input. Quello di cui ho bisogno è:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

L' big_arraydovrebbe avere una forma (10,4). Come fare questo?


MODIFICARE:

Voglio aggiungere il seguente chiarimento. Sono consapevole di poter definire big_array = numpy.zeros((10,4))e quindi riempirlo. Tuttavia, ciò richiede di specificare in anticipo la dimensione di big_array. Conosco le dimensioni in questo caso, ma se non lo facessi? Quando usiamo la .appendfunzione per estendere l'elenco in Python, non abbiamo bisogno di conoscere in anticipo la sua dimensione finale. Mi chiedo se esiste qualcosa di simile per creare un array più grande da array più piccoli, iniziando con un array vuoto.


Per inciso il tuo primo esempio di codice può essere scritto in modo ordinato e succintamente come una lista di comprensione: [i for i in range(5)]. (Equivalentemente: list(range(5))anche se questo è un esempio inventato.)
Katriel,

quale soluzione ha funzionato per te? sto cercando di fare qualcosa di simile come x = numpy.array()il modo in cui faremmo una lista come y = []; ma non ha funzionato
kRazzy R

Risposte:


160

numpy.zeros

Restituisce un nuovo array di forma e tipo, pieno di zeri.

o

numpy.ones

Restituisce un nuovo array di una determinata forma e tipo, pieno di quelli.

o

numpy.empty

Restituisce un nuovo array di forma e tipo dati, senza inizializzare le voci.


Tuttavia, la mentalità in cui costruiamo un array aggiungendo elementi a un elenco non è molto usata in numpy, perché è meno efficiente (i tipi di dati numpy sono molto più vicini agli array C sottostanti). Al contrario, è necessario preallocare l'array nella dimensione desiderata e quindi compilare le righe. Puoi usare numpy.appendse devi, però.


2
So che posso impostare big_array = numpy.zeros e quindi riempirlo con i piccoli array creati. Ciò, tuttavia, mi richiede di specificare in anticipo la dimensione di big_array. Non c'è niente come .append della funzione list in cui non ho le dimensioni specificate in anticipo. Grazie!
Curious2learn,

2
@ Curious2learn. No, non c'è niente di meglio che aggiungere in Numpy. Esistono funzioni che concatenano gli array o li impilano creando nuovi array, ma non lo fanno aggiungendo. Ciò è dovuto al modo in cui le strutture di dati sono impostate. Gli array Numpy sono fatti per essere veloci grazie alla possibilità di memorizzare valori più compatti, ma devono avere dimensioni fisse per ottenere questa velocità. Gli elenchi Python sono progettati per essere più flessibili a costo di velocità e dimensioni.
Justin Peel,

3
@Curious: beh, c'è un appendintorpidito. È solo che è meno efficiente non preallocare (in questo caso, molto meno efficiente, poiché appending copia ogni volta l'intero array), quindi non è una tecnica standard.
Katriel,

1
Cosa succede se solo una parte np.emptydell'array è riempita da valori? E i rimanenti oggetti "vuoti"?
Lee,

1
Se si conosce lo sa solo la larghezza (ad esempio necessario per np.concatenate()), è possibile inizializzare con: np.empty((0, some_width)). 0, quindi il tuo primo array non sarà immondizia.
NumesSanguis,

40

Il modo in cui lo faccio di solito è creando un elenco regolare, quindi aggiungendo le mie cose in esso e infine trasformando l'elenco in un array intorpidito come segue:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

ovviamente il tuo oggetto finale occupa il doppio dello spazio nella memoria durante la fase di creazione, ma accodare alla lista di Python è molto veloce e anche la creazione usando np.array ().


11
Questa non è la strada da percorrere se si conoscono le dimensioni dell'array in anticipo , tuttavia ... Finisco per utilizzare questo metodo frequentemente quando non so quanto sarà grande l'array. Ad esempio, durante la lettura di dati da un file o da un altro processo. Non è poi così terribile come potrebbe sembrare all'inizio poiché pitone e intorpidimento sono piuttosto intelligenti.
travc,

18

Introdotto in numpy 1.8:

numpy.full

Restituisce un nuovo array di forma e tipo dati, riempito con fill_value.

Esempi:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

13

Analogo di array per i pitoni

a = []
for i in range(5):
    a.append(i)

è:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)

5
@ NicholasTJ: empty((0))inizializza una matrice numpy.
Adobe,

2
le parentesi in np.empty ((0)) sono ridondanti.
Szymon Roziewski,

7

numpy.fromiter() è quello che stai cercando:

big_array = numpy.fromiter(xrange(5), dtype="int")

Funziona anche con le espressioni del generatore, ad esempio:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Se si conosce in anticipo la lunghezza dell'array, è possibile specificarlo con un argomento facoltativo "count".


2
In realtà ho eseguito timeit e penso che np.fromiter () potrebbe essere più lento di np.array (). timeit ("np.array (i for i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, vs. timeit ("np.fromiter ((i for i in xrange ( 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117

6

Si desidera evitare il più esplicitamente i cicli espliciti quando si esegue l'array computing, in quanto ciò riduce il guadagno di velocità da tale forma di elaborazione. Esistono diversi modi per inizializzare una matrice numpy. Se lo vuoi pieno di zeri, fai come ha detto katrielalex:

big_array = numpy.zeros((10,4))

EDIT: che tipo di sequenza stai facendo? È necessario controllare le diverse funzioni intorpidite che creano matrici, come numpy.linspace(start, stop, size)(numero equidistante) o numpy.arange(start, stop, inc). Ove possibile, queste funzioni renderanno le matrici sostanzialmente più veloci rispetto allo stesso lavoro in loop espliciti


5

Per il tuo primo esempio di array usa,

a = numpy.arange(5)

Per inizializzare big_array, utilizzare

big_array = numpy.zeros((10,4))

Ciò presuppone che si desideri inizializzare con zeri, il che è abbastanza tipico, ma ci sono molti altri modi per inizializzare un array in numpy .

Modifica: se non conosci in anticipo la dimensione di big_array, in genere è meglio creare prima un elenco Python usando append e, quando hai tutto raccolto nell'elenco, converti questo elenco in un array numpy usando numpy.array(mylist). La ragione di ciò è che gli elenchi dovrebbero crescere in modo molto efficiente e rapido, mentre numpy.concatenate sarebbe molto inefficiente poiché le matrici numpy non cambiano facilmente dimensione. Ma una volta che tutto viene raccolto in un elenco e si conosce la dimensione finale dell'array, un array intorpidito può essere costruito in modo efficiente.


5

Per inizializzare una matrice numpy con una matrice specifica:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

produzione:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]

3

Ogni volta che ti trovi nella seguente situazione:

a = []
for i in range(5):
    a.append(i)

e vuoi qualcosa di simile in numpy, diverse risposte precedenti hanno indicato modi per farlo, ma come ha sottolineato @katrielalex questi metodi non sono efficienti. Il modo più efficiente per farlo è creare un lungo elenco e quindi rimodellarlo nel modo desiderato dopo averne un lungo elenco. Ad esempio, supponiamo che io stia leggendo alcune righe da un file e ogni riga ha un elenco di numeri e voglio costruire una matrice numpy di forma (numero di righe lette, lunghezza del vettore in ogni riga). Ecco come lo farei in modo più efficiente:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array

2

Mi rendo conto che è un po 'tardi, ma non ho notato nessuna delle altre risposte che menzionano l'indicizzazione nell'array vuoto:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

In questo modo, preallocate l'intero array di risultati numpy.emptye compilate le righe mentre procedete utilizzando l'assegnazione indicizzata.

È assolutamente sicuro preallocare emptyinvece che zerosnell'esempio che hai dato, poiché stai garantendo che l'intero array verrà riempito con i blocchi generati.


2

Suggerirei prima di definire la forma. Quindi scorrere su di esso per inserire valori.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])

1

Forse qualcosa del genere si adatta alle tue esigenze ..

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Che produce il seguente output

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.