Як додати новий рядок до порожнього масиву numpy


158

Використовуючи стандартні масиви Python, я можу зробити наступне:

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

Однак я не можу зробити те ж саме в нумері. Наприклад:

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]

Я також розглядав vstack, але коли я використовую vstackпорожній масив, я отримую:

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

Тож як я можу додати новий рядок до порожнього масиву в numpy?


1
Якщо він порожній, навіщо турбуватися? Просто почніть з масиву, що містить лише перший рядок.
jonrsharpe

10
Мені просто хочеться знати, чи можна додати до порожнього нумерованого масиву. Іноді складніше писати такий код, оскільки операції з додаванням знаходяться в циклі.
Тоні Старк

5
З огляду на те , як Numpy масиви роботи, ви набагато краще будувати порожній масив потім покласти дані, наприклад , див stackoverflow.com/questions/568962 / ...
jonrsharpe

Відповіді:


227

Спосіб "запустити" масив, який ви хочете, це:

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

Що є порожнім масивом, але має належну розмірність.

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

Тоді обов’язково додайте осі 0:

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

Але, @jonrsharpe має рацію. Насправді, якщо ви збираєтесь додавати в циклі, було б набагато швидше додати до списку, як у вашому першому прикладі, а потім перетворити в масивний масив наприкінці, оскільки ви дійсно не використовуєте numpy як призначений під час циклу:

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

Числовий спосіб зробити це залежить від вашої заявки, але це буде більше:

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

що робити, якщо мені доведеться це зробити 10 ^ 5 або 10 ^ 6 разів? схоже, що жоден із цих методів не буде дотриманий. будь-яка пропозиція?
Rho Phi

@ Роберто, зазвичай існує певний спосіб визначити розмір або форму (принаймні, значення було б кращим) масиву заздалегідь. Думаєте, ви можете це зробити? Подання дійсно має бути одноразовою або дворазовою операцією.
askewchan

іноді ви не можете вгадати розміри, це життя. Однак ви можете виділити достатньо великий масив і надати значення його переглядам. Мені це не подобається, тому що є небажані значення, які треба знайти спосіб «замаскувати». Ця ідея маскування дійсно не відповідає моєму смаку.
Rho Phi

Маскувати не потрібно, просто скибочку! a = a[:N] Хоча я переконаний, що ви повинні знайти спосіб його векторизації (опублікуйте нове запитання зі своєю специфікою, якщо вам потрібна допомога) або просто використовувати списки, поки цикл не закінчиться.
askewchan

29

Ось моє рішення:

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

Отриманий масив має тип об’єкта, що в певних випадках не прийнятно
zer0fool

26

У цьому випадку ви можете використовувати функції np.hstack та 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]]

Ви також можете використовувати функцію np.concatenate.

Ура


7
Не працює, якщо другий масив має розмір> = 2 подібних ((2, 2)). Мені здається, немає можливості уникнути межових випадків, якщо ви збираєте масиви з порожніх шляхом конкатенації.
Таозі

Не гарне рішення, оскільки потрібно перевіряти розмір кожного разу.
SKR

1

використовуючи спеціальне визначення типу, для мене працювало:

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'])

1

У разі додавання нових рядків для масиву в циклі, призначте масив безпосередньо для циклу замість ініціалізації порожнього масиву.

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

Це в основному корисно, коли форма масиву невідома


0

Я хочу зробити цикл for, але з методом askewchan він не працює добре, тому я його змінив.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.