Jak dodać nowy wiersz do pustej tablicy numpy

158

Korzystając ze standardowych tablic Pythona, mogę wykonać następujące czynności:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
# arr is now [[1,2,3],[4,5,6]]

Jednak nie mogę zrobić tego samego w odrętwieniu. Na przykład:

arr = np.array([])
arr = np.append(arr, np.array([1,2,3]))
arr = np.append(arr, np.array([4,5,6]))
# arr is now [1,2,3,4,5,6]

Zajrzałem też vstack, ale kiedy używam vstackna pustej tablicy, otrzymuję:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Jak więc dołączyć nowy wiersz do pustej tablicy w numpy?

Tony Stark
źródło
1
Jeśli jest pusty, po co się przejmować? Po prostu zacznij od tablicy zawierającej tylko pierwszy wiersz.
jonrsharpe
10
Chcę tylko wiedzieć, czy można dołączyć do pustej tablicy numpy. Czasami pisanie takiego kodu jest czystsze, ponieważ operacje dołączania są w pętli.
Tony Stark
5
Biorąc pod uwagę sposób działania tablic numpy, znacznie lepiej jest budować pustą tablicę niż wprowadzać dane, np. Zobacz stackoverflow.com/questions/568962/ ...
jonrsharpe

Odpowiedzi:

227

Sposobem na „uruchomienie” tablicy, którą chcesz, jest:

arr = np.empty((0,3), int)

Która jest pustą tablicą, ale ma odpowiednią wymiarowość.

>>> arr
array([], shape=(0, 3), dtype=int64)

Następnie pamiętaj, aby dołączyć wzdłuż osi 0:

arr = np.append(arr, np.array([[1,2,3]]), axis=0)
arr = np.append(arr, np.array([[4,5,6]]), axis=0)

Ale @jonrsharpe ma rację. W rzeczywistości, jeśli zamierzasz dołączać w pętli, byłoby znacznie szybciej dołączyć do listy, jak w pierwszym przykładzie, a następnie przekonwertować na tablicę numpy na końcu, ponieważ tak naprawdę nie używasz numpy jako przeznaczone podczas pętli:

In [210]: %%timeit
   .....: l = []
   .....: for i in xrange(1000):
   .....:     l.append([3*i+1,3*i+2,3*i+3])
   .....: l = np.asarray(l)
   .....: 
1000 loops, best of 3: 1.18 ms per loop

In [211]: %%timeit
   .....: a = np.empty((0,3), int)
   .....: for i in xrange(1000):
   .....:     a = np.append(a, 3*i+np.array([[1,2,3]]), 0)
   .....: 
100 loops, best of 3: 18.5 ms per loop

In [214]: np.allclose(a, l)
Out[214]: True

Sposób numpythonic, aby to zrobić, zależy od aplikacji, ale byłby bardziej podobny do:

In [220]: timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 µs per loop

In [221]: np.allclose(a, n)
Out[221]: True
askewchan
źródło
co jeśli będę musiał to zrobić 10 ^ 5 lub 10 ^ 6 razy? wydaje się, że żadna z tych metod się nie sprawdzi. jakieś sugestie?
Rho Phi,
@Roberto, zwykle istnieje sposób na wcześniejsze określenie rozmiaru lub kształtu (przynajmniej wartości byłyby preferowane). Czy myślisz, że możesz to zrobić? Dołączanie powinno tak naprawdę być operacją jednorazową lub dwukrotną.
askewchan
czasami nie możesz odgadnąć wymiarów, to jest życie. Możesz jednak przydzielić wystarczająco dużą tablicę i nadać wartości jej widokom. Nie podoba mi się to jednak, bo są niepożądane wartości, które trzeba znaleźć sposób na „zamaskowanie”. Ten pomysł maskowania naprawdę nie pasuje do mojego gustu.
Rho Phi,
Nie ma potrzeby maskowania, po prostu pokrój! a = a[:N] Chociaż mocno wierzę, że powinieneś znaleźć sposób na wektoryzację tego (opublikuj nowe pytanie ze swoimi szczegółami, jeśli potrzebujesz pomocy) lub po prostu używaj list, aż pętla się skończy.
askewchan
29

Oto moje rozwiązanie:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
np_arr = np.array(arr)
just4fun
źródło
Wynikowa tablica ma dtype obiektu, co w niektórych przypadkach jest
niedopuszczalne
26

W takim przypadku możesz chcieć użyć funkcji np.hstack i np.vstack

arr = np.array([])
arr = np.hstack((arr, np.array([1,2,3])))
# arr is now [1,2,3]

arr = np.vstack((arr, np.array([4,5,6])))
# arr is now [[1,2,3],[4,5,6]]

Możesz również użyć funkcji np.concatenate.

Twoje zdrowie

mrcl
źródło
7
Nie będzie działać, jeśli druga tablica ma wymiar> = 2 jak jedności ((2, 2)). Wydaje mi się, że nie ma sposobu na uniknięcie przypadków granicznych, jeśli tworzysz tablice z pustych przez konkatenację.
Taozi
Nie jest to dobre rozwiązanie, ponieważ za każdym razem trzeba sprawdzać wymiar.
SKR
1

używając niestandardowej definicji typu, zadziałało:

import numpy

# define custom dtype
type1 = numpy.dtype([('freq', numpy.float64, 1), ('amplitude', numpy.float64, 1)])
# declare empty array, zero rows but one column
arr = numpy.empty([0,1],dtype=type1)
# store row data, maybe inside a loop
row = numpy.array([(0.0001, 0.002)], dtype=type1)
# append row to the main array
arr = numpy.row_stack((arr, row))
# print values stored in the row 0
print float(arr[0]['freq'])
print float(arr[0]['amplitude'])
boclodoa
źródło
1

W przypadku dodawania nowych wierszy dla tablicy w pętli, przypisz tablicę bezpośrednio po raz pierwszy w pętli zamiast inicjowania pustej tablicy.

for i in range(0,len(0,100)):
    SOMECALCULATEDARRAY = .......
    if(i==0):
        finalArrayCollection = SOMECALCULATEDARRAY
    else:
        finalArrayCollection = np.vstack(finalArrayCollection,SOMECALCULATEDARRAY)

Jest to przydatne głównie wtedy, gdy kształt tablicy jest nieznany

Rajesh_Saladi
źródło
0

Chcę zrobić pętlę for, ale z metodą askewchan nie działa dobrze, więc ją zmodyfikowałem.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
Qingdong Wang
źródło