Jak utworzyć pustą tablicę / macierz w NumPy?

311

Nie mogę wymyślić, jak użyć tablicy lub macierzy w sposób, w jaki normalnie użyłbym listy. Chcę utworzyć pustą tablicę (lub macierz), a następnie dodawać do niej jedną kolumnę (lub wiersz) na raz.

W tej chwili jedynym sposobem, aby to zrobić, jest:

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

Gdyby to była lista, zrobiłbym coś takiego:

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

Czy istnieje sposób na użycie tego rodzaju notacji w przypadku tablic lub macierzy NumPy ?

Ben
źródło

Odpowiedzi:

441

Masz niewłaściwy model mentalny do efektywnego korzystania z NumPy. Tablice NumPy są przechowywane w ciągłych blokach pamięci. Jeśli chcesz dodać wiersze lub kolumny do istniejącej tablicy, cała tablica musi zostać skopiowana do nowego bloku pamięci, tworząc luki dla nowych elementów do przechowywania. Jest to bardzo nieefektywne, jeśli jest wykonywane wielokrotnie w celu zbudowania tablicy.

W przypadku dodawania wierszy najlepiej jest utworzyć tablicę, która będzie tak duża, jak ostatecznie będzie zestaw danych, a następnie dodawać do niej dane wiersz po rzędzie:

>>> 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.]])
Stephen Simmons
źródło
123
Istnieje również funkcja numpy.empty (), jeśli nie trzeba zerować tablicy.
janneb
21
Jaka jest korzyść z używania empty () zamiast zer ()?
Zach
45
że jeśli chcesz od razu zainicjować je danymi, oszczędzasz koszty ich zerowania.
marcorossi
16
@maracorossi .empty()oznacza, że ​​można znaleźć losowe wartości w komórkach, ale tablica jest tworzona szybciej niż np. za pomocą .zeros()?
user3085931,
6
@ user3085931 tak!
Nathan
98

Tablica NumPy jest bardzo inną strukturą danych niż lista i została zaprojektowana do użycia na różne sposoby. Twoje użycie hstackjest potencjalnie bardzo nieefektywne ... za każdym razem, gdy go wywołasz, wszystkie dane z istniejącej tablicy są kopiowane do nowej. ( appendFunkcja będzie miała ten sam problem.) Jeśli chcesz budować swoją matrycę po jednej kolumnie na raz, najlepiej jest zachować ją na liście, dopóki nie zostanie ukończona, a dopiero potem przekształcić ją w tablicę.

na przykład


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

itemmoże być listą, tablicą lub dowolnym iterowalnym, o ile każdy itemma taką samą liczbę elementów.
W tym konkretnym przypadku ( datajest to możliwe do wielokrotnego przechowywania kolumny macierzy) możesz po prostu użyć


mat = numpy.array(data)

(Należy również pamiętać, że używanie listjako nazwy zmiennej prawdopodobnie nie jest dobrą praktyką, ponieważ maskuje typ wbudowany tą nazwą, co może prowadzić do błędów).

EDYTOWAĆ:

Jeśli z jakiegoś powodu naprawdę chcesz utworzyć pustą tablicę, możesz po prostu użyć numpy.array([]), ale jest to rzadko przydatne!

Greg Ball
źródło
1
Czy tablice / macierze numpy zasadniczo różnią się od macierzy Matlab?
levesque
1
Jeśli z jakiegoś powodu trzeba zdefiniować pustą tablicę, ale o stałej szerokości (np np.concatenate()), można użyć: np.empty((0, some_width)). 0, więc twoja pierwsza tablica nie będzie śmieciami.
NumesSanguis
56

Aby utworzyć pustą tablicę wielowymiarową w NumPy (np. Tablicę 2D m*ndo przechowywania macierzy), na wypadek, gdybyś nie wiedział, mile wierszy dołączysz i nie przejmujesz się kosztami obliczeniowymi wspomnianymi przez Stephena Simmonsa (a mianowicie ponownym zbudowaniem tablica na każdym dołącz), można wycisnąć do 0 wymiaru, do którego chcesz dołączyć do: X = np.empty(shape=[0, n]).

W ten sposób możesz na przykład użyć (tutaj, o m = 5którym zakładamy, że nie wiedzieliśmy podczas tworzenia pustej matrycy, i 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

co da ci:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]
Franck Dernoncourt
źródło
1
To powinna być odpowiedź na zadane pytanie OP, dla przypadku użycia, w którym nie znasz #row z góry lub chcesz obsłużyć przypadek, w którym jest 0 wierszy
Spcogg drugi
26

Dużo się nad tym zastanawiałem, ponieważ musiałem użyć tablicy numpy.array jako zestawu w jednym z moich szkolnych projektów i musiałem zostać zainicjowany pusty ... Nie znalazłem żadnej istotnej odpowiedzi na temat przepełnienia stosu, więc zacząłem doodling czegoś.

# 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)

Wynik będzie:

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

Dlatego możesz bezpośrednio zainicjować tablicę np w następujący sposób:

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

Mam nadzieję, że to pomoże.

Andrei Paga
źródło
To nie działa dla tablic, jak w pytaniu, ale może być przydatne dla wektorów.
divenex
a=np.array([])wydaje się domyślnie float64
P i
7

Możesz użyć funkcji dołączania. Dla rzędów:

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

Dla kolumn:

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

EDYCJA
Oczywiście, jak wspomniano w innych odpowiedziach, chyba że wykonujesz pewne przetwarzanie (np. Inwersję) na macierzy / macierzy KAŻDY raz, gdy coś do niej dodasz, po prostu stworzę listę, dołączę do niej, a następnie przekonwertuję na szyk.

Il-Bhima
źródło
3

Jeśli nie znasz ostatecznego rozmiaru tablicy, możesz zwiększyć jej rozmiar w następujący sposób:

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.]]
  • Zwróć uwagę na 0w pierwszym wierszu.
  • numpy.appendjest inną opcją. Wzywa numpy.concatenate.
cyborg
źródło
3

Możesz go zastosować do zbudowania dowolnego rodzaju tablicy, np. Zer:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]
Ali G.
źródło
4
Jeśli chcesz to zrobić w czystym pythonie, a= [0] * 5jest proste rozwiązanie
Makers_F,
3

Oto kilka obejść, dzięki którym numpys wyglądają bardziej jak Listy

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

WYJŚCIE: tablica ([2., 24.])

Dariusz
źródło
2

W zależności od tego, do czego go używasz, może być konieczne określenie typu danych (patrz „dtype” ).

Na przykład, aby utworzyć tablicę 2D o 8-bitowych wartościach (odpowiednią do użycia jako obraz monochromatyczny):

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

W przypadku obrazu RGB podaj liczbę kanałów kolorów w kształcie: shape=(H,W,3)

Możesz również rozważyć zainicjowanie zera numpy.zeroszamiast zamiast numpy.empty. Zobacz notatkę tutaj .

nobar
źródło
1

Myślę, że chcesz obsłużyć większość pracy z listami, a następnie użyć wyniku jako macierzy. Może to jest sposób;

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

mat = np.matrix(ur_list)
runo
źródło
1

Myślę, że możesz stworzyć pustą tablicę numpy, taką jak:

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

Ten format jest przydatny, gdy chcesz dołączyć tablicę numpy w pętli.

veeresh d
źródło
0

Aby utworzyć pustą tablicę NumPy bez określania jej kształtu, należy:

1.

arr = np.array([]) 

preferowane. bo wiesz, że będziesz używać tego jako numpy.

2)

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

NumPy konwertuje to później na typ np.ndarray, bez dodatkowych [] dimionsion.

Pedram
źródło