zainicjuj tablicę numpy


129

Czy istnieje sposób na zainicjowanie tablicy numpy kształtu i dodanie do niej? Wyjaśnię, czego potrzebuję, na przykładzie listy. Jeśli chcę stworzyć listę obiektów generowanych w pętli, mogę:

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

Chcę zrobić coś podobnego z tablicą numpy. Wiem o vstack, concatenate itp. Jednak wydaje się, że wymagają one dwóch tablic numpy jako danych wejściowych. Potrzebuję:

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

big_arrayPowinny mieć kształt (10,4). Jak to zrobić?


EDYTOWAĆ:

Chcę dodać następujące wyjaśnienie. Mam świadomość, że potrafię to zdefiniować, big_array = numpy.zeros((10,4))a następnie wypełnić. Wymaga to jednak wcześniejszego określenia rozmiaru tablicy big_array. W tym przypadku znam rozmiar, ale co jeśli nie? Kiedy używamy .appendfunkcji do rozszerzania listy w Pythonie, nie musimy z góry znać jej ostatecznego rozmiaru. Zastanawiam się, czy istnieje coś podobnego do tworzenia większej tablicy z mniejszych tablic, zaczynając od pustej tablicy.


Nawiasem mówiąc Twoja pierwsza próbka kod może być napisany starannie i zwięźle jako listowego: [i for i in range(5)]. (Równoważnie: list(range(5))chociaż jest to wymyślony przykład.)
Katriel

jakie rozwiązanie zadziałało dla Ciebie? próbuję zrobić coś podobnego, tak jak x = numpy.array()robilibyśmy to z listą y = []; ale to nie zadziałało
kRazzy R

Odpowiedzi:


160

numpy.zeros

Zwraca nową tablicę o podanym kształcie i typie, wypełnioną zerami.

lub

numpy.ones

Zwraca nową tablicę o podanym kształcie i typie, wypełnioną jedynkami.

lub

numpy.empty

Zwraca nową tablicę o podanym kształcie i typie, bez inicjalizacji wpisów.


Jednak mentalność, w której konstruujemy tablicę przez dołączanie elementów do listy, nie jest zbytnio używana w numpy, ponieważ jest mniej wydajna (typy danych numpy są znacznie bliższe bazowym tablicom C). Zamiast tego należy wstępnie przydzielić tablicę do wymaganego rozmiaru, a następnie wypełnić wiersze. Możesz jednak użyć, numpy.appendjeśli musisz.


2
Wiem, że mogę ustawić big_array = numpy.zeros, a następnie wypełnić go utworzonymi małymi tablicami. To jednak wymaga ode mnie wcześniejszego określenia rozmiaru big_array. Czy nie ma nic podobnego do .append funkcji listy, w której nie mam z góry określić rozmiaru. Dzięki!
Curious2learn

2
@ Curious2learn. Nie, w Numpy nie ma nic lepszego niż dołączanie. Istnieją funkcje, które łączą tablice lub układają je w stosy, tworząc nowe tablice, ale nie robią tego przez dołączanie. Wynika to ze sposobu, w jaki skonfigurowane są struktury danych. Tablice Numpy są wykonane tak, aby były szybkie ze względu na możliwość bardziej zwartego przechowywania wartości, ale muszą mieć stały rozmiar, aby uzyskać tę prędkość. Listy Pythona są zaprojektowane tak, aby były bardziej elastyczne kosztem szybkości i rozmiaru.
Justin Peel

3
@ Ciekawe: cóż, jest appendw numpy. Tyle, że mniej efektywne jest nieprzydzielanie wstępne (w tym przypadku znacznie mniej wydajne, ponieważ appendkopiowanie całej tablicy za każdym razem), więc nie jest to standardowa technika.
Katriel

1
A co, jeśli tylko część np.emptytablicy jest wypełniona wartościami? A co z pozostałymi „pustymi” przedmiotami?
Lee

1
Jeśli wiesz, wiem tylko szerokość (np potrzebne np.concatenate()) można zainicjować z: np.empty((0, some_width)). 0, więc twoja pierwsza tablica nie będzie śmieci.
NumesSanguis

40

Sposób, w jaki zwykle to robię, polega na utworzeniu zwykłej listy, a następnie dołączeniu do niej swoich rzeczy i ostatecznie przekształceniu listy w tablicę numpy w następujący sposób:

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

oczywiście twój ostateczny obiekt zajmuje dwa razy więcej miejsca w pamięci na etapie tworzenia, ale dołączanie do listy Pythona jest bardzo szybkie, a tworzenie również za pomocą np.array ().


11
Nie jest to właściwa droga, jeśli znasz rozmiar tablicy z wyprzedzeniem , jednak ... Często używam tej metody, gdy nie wiem, jak duża będzie tablica. Na przykład podczas odczytu danych z pliku lub innego procesu. To naprawdę nie jest tak okropne, jak mogłoby się początkowo wydawać, ponieważ Python i Numpy są całkiem sprytni.
travc

18

Wprowadzony w numpy 1.8:

numpy.full

Zwraca nową tablicę o podanym kształcie i typie, wypełnioną wartością fill_value.

Przykłady:

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

Tablica analogowa dla Pythona

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

jest:

import numpy as np

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

5
@NicholasTJ: empty((0))inicjalizuje tablicę numpy.
Adobe,

2
nawiasy w np.empty ((0)) są zbędne.
Szymon Roziewski

7

numpy.fromiter() to czego szukasz:

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

Działa również z wyrażeniami generatora, np .:

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

Jeśli znasz wcześniej długość tablicy, możesz określić ją za pomocą opcjonalnego argumentu „count”.


2
Właściwie uruchomiłem timeit i myślę, że np.fromiter () może być wolniejszy niż np.array (). timeit ("np.array (i for i in xrange (100))", setup = "import numpy as np", number = 10000) -> 0,02539992332458496, versus timeit ("np.fromiter ((i for i in xrange ( 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117

6

Podczas wykonywania obliczeń tablicowych chcesz w jak największym stopniu unikać jawnych pętli, ponieważ zmniejsza to wzrost szybkości wynikający z tej formy przetwarzania. Istnieje wiele sposobów inicjalizacji tablicy numpy. Jeśli chcesz, aby był wypełniony zerami, zrób tak, jak powiedziała Katrielalex:

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

EDYCJA: Jakiego rodzaju sekwencję tworzysz? Powinieneś sprawdzić różne funkcje numpy, które tworzą tablice, takie jak numpy.linspace(start, stop, size)(równo rozmieszczona liczba) lub numpy.arange(start, stop, inc). Tam, gdzie to możliwe, te funkcje spowodują, że tablice będą znacznie szybsze niż wykonywanie tej samej pracy w jawnych pętlach


5

W pierwszym przykładzie tablicy użyj

a = numpy.arange(5)

Aby zainicjować big_array, użyj

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

Zakłada się, że chcesz zainicjalizowaćzerami, co jest dość typowe, ale istnieje wiele innych sposobów inicjalizacji tablicy w numpy .

Edycja: Jeśli nie znasz wcześniej rozmiaru big_array, ogólnie najlepiej jest najpierw zbudować listę Pythona za pomocą append, a kiedy masz wszystko zebrane na liście, przekonwertuj ją na tablicę numpy za pomocą numpy.array(mylist). Powodem tego jest to, że listy mają rosnąć bardzo wydajnie i szybko, podczas gdy numpy.concatenate byłby bardzo nieefektywny, ponieważ tablice numpy nie zmieniają łatwo rozmiaru. Ale kiedy wszystko jest zebrane na liście i znasz ostateczny rozmiar tablicy, tablicę numpy można skutecznie skonstruować.


5

Aby zainicjować tablicę numpy z określoną macierzą:

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

wynik:

(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

Ilekroć znajdujesz się w następującej sytuacji:

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

i chcesz czegoś podobnego w numpy, kilka poprzednich odpowiedzi wskazywało sposoby na zrobienie tego, ale jak @katrielalex wskazał, te metody nie są wydajne. Skutecznym sposobem jest utworzenie długiej listy, a następnie przekształcenie jej w żądany sposób po utworzeniu długiej listy. Na przykład, powiedzmy, że czytam kilka wierszy z pliku, a każdy wiersz ma listę liczb i chcę zbudować tablicę numpy kształtu (liczba odczytanych wierszy, długość wektora w każdym wierszu). Oto jak zrobiłbym to wydajniej:

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

Zdaję sobie sprawę, że to trochę za późno, ale nie zauważyłem żadnej innej odpowiedzi wspominającej o indeksowaniu do pustej tablicy:

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

W ten sposób całą tablicę wyników przydzielasz wstępnie za pomocą numpy.empty przydzielasz i wypełniasz wiersze w trakcie, używając przypisania indeksowanego.

Całkowicie bezpieczne jest dokonanie wstępnej alokacji emptyzamiast zerosw podanym przykładzie, ponieważ gwarantujesz, że cała tablica zostanie wypełniona wygenerowanymi fragmentami.


2

Proponuję najpierw zdefiniować kształt. Następnie wykonaj iterację, aby wstawić wartości.

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

Może coś takiego będzie pasowało do Twoich potrzeb.

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)

Który daje następujący wynik

[[ 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.]]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.