Come posso creare una matrice / matrice vuota in NumPy?


311

Non riesco a capire come usare un array o una matrice nel modo in cui userei normalmente un elenco. Voglio creare un array (o matrice) vuoto e quindi aggiungere una colonna (o riga) alla volta.

Al momento l'unico modo per trovare questo è come:

mat = None
for col in columns:
    if mat is None:
        mat = col
    else:
        mat = hstack((mat, col))

Considerando che se fosse un elenco, farei qualcosa del genere:

list = []
for item in data:
    list.append(item)

Esiste un modo per usare quel tipo di notazione per matrici o matrici NumPy ?

Risposte:


441

Hai il modello mentale sbagliato per usare NumPy in modo efficiente. Le matrici NumPy sono memorizzate in blocchi contigui di memoria. Se si desidera aggiungere righe o colonne a un array esistente, l'intero array deve essere copiato in un nuovo blocco di memoria, creando spazi per i nuovi elementi da archiviare. Questo è molto inefficiente se fatto ripetutamente per costruire un array.

Nel caso di aggiunta di righe, la soluzione migliore è creare un array grande quanto il tuo set di dati alla fine sarà, quindi aggiungere i dati riga per riga:

>>> import numpy
>>> a = numpy.zeros(shape=(5,2))
>>> a
array([[ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])
>>> a[0] = [1,2]
>>> a[1] = [2,3]
>>> a
array([[ 1.,  2.],
   [ 2.,  3.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])

123
C'è anche numpy.empty () se non è necessario azzerare l'array.
janneb,

21
Qual è il vantaggio di usare empty () su zeros ()?
Zach,

45
che se lo inizializzi immediatamente con i tuoi dati, risparmierai il costo dell'azzeramento.
marcorossi,

16
@maracorossi .empty()significa che si possono trovare valori casuali nelle celle, ma l'array viene creato più velocemente rispetto ad esempio con .zeros()?
user3085931,

6
@ user3085931 sì!
Nathan,

98

Un array NumPy è una struttura di dati molto diversa da un elenco ed è progettato per essere utilizzato in diversi modi. Il tuo uso di hstackpotenzialmente è molto inefficiente ... ogni volta che lo chiami, tutti i dati nell'array esistente vengono copiati in uno nuovo. (La appendfunzione avrà lo stesso problema.) Se vuoi costruire la tua matrice una colonna alla volta, potresti essere meglio tenerlo in un elenco fino a quando non è finito, e solo allora convertirlo in un array.

per esempio


mylist = []
for item in data:
    mylist.append(item)
mat = numpy.array(mylist)

itempuò essere un elenco, un array o qualsiasi iterabile, purché ciascuno itemabbia lo stesso numero di elementi.
In questo caso particolare ( dataè un po 'iterabile che contiene le colonne della matrice) puoi semplicemente usare


mat = numpy.array(data)

(Si noti inoltre che l'utilizzo listcome nome di variabile non è probabilmente una buona pratica poiché maschera il tipo incorporato con quel nome, il che può portare a bug.)

MODIFICARE:

Se per qualche motivo vuoi davvero creare un array vuoto, puoi semplicemente usarlo numpy.array([]), ma questo è raramente utile!


1
Le matrici / matrici intorpidite sono fondamentalmente diverse da quelle di Matlab?
levesque

1
Se per qualche motivo è necessario definire un array vuoto, ma con larghezza fissa (ad esempio np.concatenate()), si può utilizzare: np.empty((0, some_width)). 0, quindi il tuo primo array non sarà immondizia.
NumesSanguis,

56

Per creare un array multidimensionale vuoto in NumPy (ad esempio un array 2D m*nper memorizzare la matrice), nel caso in cui non si sappia mquante righe si aggiungeranno e non si preoccupi del costo computazionale menzionato da Stephen Simmons (ovvero la ricostruzione del serie ad ogni accodamento), si può spremere a 0 la dimensione a cui si desidera aggiungere a: X = np.empty(shape=[0, n]).

In questo modo puoi usare ad esempio (qui m = 5che presumiamo di non conoscere durante la creazione della matrice vuota e n = 2):

import numpy as np

n = 2
X = np.empty(shape=[0, n])

for i in range(5):
    for j  in range(2):
        X = np.append(X, [[i, j]], axis=0)

print X

che ti darà:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]

1
Questa dovrebbe essere la risposta alla domanda posta dall'OP, per il caso d'uso in cui non si conosce anticipatamente #row o si desidera gestire il caso in cui vi siano 0 righe
Spcogg il secondo

26

Ci ho pensato molto perché avevo bisogno di usare un numpy.array come set in uno dei miei progetti scolastici e dovevo essere inizializzato vuoto ... Non ho trovato nessuna risposta pertinente qui su Stack Overflow, quindi ho iniziato scarabocchiare qualcosa.

# Initialize your variable as an empty list first
In [32]: x=[]
# and now cast it as a numpy ndarray
In [33]: x=np.array(x)

Il risultato sarà:

In [34]: x
Out[34]: array([], dtype=float64)

Pertanto è possibile inizializzare direttamente un array np come segue:

In [36]: x= np.array([], dtype=np.float64)

Spero che aiuti.


Questo non funziona per gli array, come nella domanda, ma può essere utile per i vettori.
divenex il

a=np.array([])sembra predefinitofloat64
P

7

È possibile utilizzare la funzione Aggiungi. Per le file:

>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],      
       [1, 2, 3]])

Per colonne:

>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],      
       [1, 2, 3, 15]])

MODIFICA
Naturalmente, come menzionato in altre risposte, a meno che tu non stia eseguendo un po 'di elaborazione (es. Inversione) sulla matrice / matrice ogni volta che aggiungi qualcosa ad esso, vorrei solo creare un elenco, accodarlo ad esso e convertirlo in un Vettore.


3

Se non conosci assolutamente le dimensioni finali dell'array, puoi aumentare le dimensioni dell'array in questo modo:

my_arr = numpy.zeros((0,5))
for i in range(3):
    my_arr=numpy.concatenate( ( my_arr, numpy.ones((1,5)) ) )
print(my_arr)

[[ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]]
  • Notare il 0nella prima riga.
  • numpy.appendè un'altra opzione. Chiama numpy.concatenate.

3

Puoi applicarlo per creare qualsiasi tipo di array, come gli zeri:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]

4
Se vuoi farlo in puro pitone, a= [0] * 5è la soluzione semplice
Makers_F

3

Ecco qualche soluzione alternativa per rendere i numpys più simili agli elenchi

np_arr = np.array([])
np_arr = np.append(np_arr , 2)
np_arr = np.append(np_arr , 24)
print(np_arr)

OUTPUT: array ([2., 24.])


2

A seconda del motivo per cui lo si utilizza, potrebbe essere necessario specificare il tipo di dati (consultare 'dtype' ).

Ad esempio, per creare un array 2D di valori a 8 bit (adatto all'uso come immagine monocromatica):

myarray = numpy.empty(shape=(H,W),dtype='u1')

Per un'immagine RGB, includere il numero di canali di colore nella forma: shape=(H,W,3)

Puoi anche considerare di inizializzare lo zero con numpy.zerosinvece di usare numpy.empty. Vedi la nota qui .


1

Penso che tu voglia gestire la maggior parte del lavoro con le liste, quindi utilizzare il risultato come matrice. Forse questo è un modo;

ur_list = []
for col in columns:
    ur_list.append(list(col))

mat = np.matrix(ur_list)

1

Penso che puoi creare array numpy vuoti come:

>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)

Questo formato è utile quando si desidera aggiungere un array numpy nel loop.


0

Per creare un array NumPy vuoto senza definirne la forma c'è un modo:

1.

arr = np.array([]) 

preferito. perché sai che lo userai come intorpidito.

2.

arr = []
# and use it as numpy. append to it or etc..

NumPy lo converte in tipo np.ndarray in seguito, senza extra [] dimionsion.


0

Forse quello che stai cercando è qualcosa del genere:

x=np.array(0)

In questo modo è possibile creare un array senza alcun elemento. È simile a:

x=[]

In questo modo sarai in grado di aggiungere in anticipo nuovi elementi al tuo array.

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.