Подтвердить что ты не робот

Неудачное добавление в пустой массив NumPy

Я пытаюсь заполнить пустой (не np.empty!) массив со значениями, используя append, но я получаю ошибку gettin:

Мой код выглядит следующим образом:

import numpy as np
result=np.asarray([np.asarray([]),np.asarray([])])
result[0]=np.append([result[0]],[1,2])

И я получаю:

ValueError: could not broadcast input array from shape (2) into shape (0)
4b9b3361

Ответ 1

numpy.append довольно отличается от list.append в python. Я знаю, что отбросил несколько программистов, новых для numpy. numpy.append больше похож на concatenate, он создает новый массив и заполняет его значениями из старого массива и добавляемыми новыми значениями. Например:

import numpy

old = numpy.array([1, 2, 3, 4])
new = numpy.append(old, 5)
print old
# [1, 2, 3, 4]
print new
# [1, 2, 3, 4, 5]
new = numpy.append(new, [6, 7])
print new
# [1, 2, 3, 4, 5, 6, 7]

Я думаю, вы могли бы достичь своей цели, сделав что-то вроде:

result = numpy.zeros((10,))
result[0:2] = [1, 2]

# Or
result = numpy.zeros((10, 2))
result[0, :] = [1, 2]

Update:

Если вам нужно создать массив numpy с использованием цикла, и вы не знаете заранее, каким будет конечный размер массива, вы можете сделать что-то вроде:

import numpy as np

a = np.array([0., 1.])
b = np.array([2., 3.])

temp = []
while True:
    rnd = random.randint(0, 100)
    if rnd > 50:
        temp.append(a)
    else:
        temp.append(b)
    if rnd == 0:
         break

 result = np.array(temp)

В моем примере результатом будет массив (N, 2), где N - число циклов, за которое цикл работал, но, очевидно, вы можете настроить его на свои нужды.

новое обновление

Ошибка, которую вы видите, не имеет ничего общего с типами, она связана с формой массивов numpy, которые вы пытаетесь объединить. Если вы делаете np.append(a, b), то должны соответствовать формы a и b. Если вы добавите (2, n) и (n,), вы получите массив (3, n). Ваш код пытается добавить (1, 0) к (2,). Эти фигуры не совпадают, поэтому вы получаете ошибку.

Ответ 2

Я мог бы неправильно понять вопрос, но если вы хотите объявить массив определенной формы, но без ничего внутри, может быть полезно следующее:

Инициализировать пустой массив:

>>> a = np.zeros((0,3)) #or np.empty((0,3)) or np.array([]).reshape(0,3)
>>> a
array([], shape=(0, 3), dtype=float64)

Теперь вы можете использовать этот массив для добавления к нему строк одинаковой формы. Помните, что числовой массив является неизменным, поэтому для каждой итерации создается новый массив:

>>> for i in range(3):
...     a = np.vstack([a, [i,i,i]])
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

np.vstack и np.hstack - это наиболее распространенный метод для объединения пустых массивов, но, исходя из Matlab, я предпочитаю np.r_ и np.c_:

Объединить 1d:

>>> a = np.zeros(0)
>>> for i in range(3):
...     a = np.r_[a, [i, i, i]]
...
>>> a
array([ 0.,  0.,  0.,  1.,  1.,  1.,  2.,  2.,  2.])

Конкатенация строк:

>>> a = np.zeros((0,3))
>>> for i in range(3):
...     a = np.r_[a, [[i,i,i]]]
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

Объединенные столбцы:

>>> a = np.zeros((3,0))
>>> for i in range(3):
...     a = np.c_[a, [[i],[i],[i]]]
...
>>> a
array([[ 0.,  1.,  2.],
       [ 0.,  1.,  2.],
       [ 0.,  1.,  2.]])

Ответ 3

Эта ошибка возникает из-за того, что вы пытаетесь определить объект формы (0) как объект формы (2). Если вы добавляете то, что хотите, не заставляя его быть равным результату [0], нет никакой проблемы:

b = np.append([result[0]], [1,2])

Но когда вы определяете результат [0] = b, вы приравниваете объекты разных фигур, и вы не можете этого сделать. Что вы пытаетесь сделать?

Ответ 4

Вот результат запуска вашего кода в Ipython. Обратите внимание, что result - это массив (2,0), 2 строки, 0 столбцов, 0 элементов. append создает массив (2,). result[0] - массив (0,). Ваше сообщение об ошибке связано с попыткой назначить этот 2-элементный массив в слот размера 0. Поскольку result - dtype=float64, для его элементов могут быть назначены только скаляры.

In [65]: result=np.asarray([np.asarray([]),np.asarray([])])

In [66]: result
Out[66]: array([], shape=(2, 0), dtype=float64)

In [67]: result[0]
Out[67]: array([], dtype=float64)

In [68]: np.append(result[0],[1,2])
Out[68]: array([ 1.,  2.])

np.array не является списком Python. Все элементы массива имеют один и тот же тип (как указано dtype). Также обратите внимание, что result не является массивом массивов.

Результат также может быть построен как

ll = [[],[]]
result = np.array(ll)

а

ll[0] = [1,2]
# ll = [[1,2],[]]

То же самое не относится к результату.

np.zeros((2,0)) также создает ваш result.

На самом деле есть еще одна причуда к result.

result[0] = 1

не изменяет значения result. Он принимает задание, но поскольку он имеет 0 столбцов, нет места для размещения 1. Это задание будет работать с результатом np.zeros((2,1)). Но это все еще не может принять список.

Но если result имеет 2 столбца, вы можете назначить список из 2-х элементов одной из своих строк.

result = np.zeros((2,2))
result[0] # == [0,0]
result[0] = [1,2]

Что именно вы хотите result выглядеть после операции append?

Ответ 5

numpy.append всегда копирует массив перед добавлением новых значений. Ваш код эквивалентен следующему:

import numpy as np
result = np.zeros((2,0))
new_result = np.append([result[0]],[1,2])
result[0] = new_result # ERROR: has shape (2,0), new_result has shape (2,)

Возможно, вы хотите сделать это?

import numpy as np
result = np.zeros((2,0))
result = np.append([result[0]],[1,2])

Ответ 6

SO thread 'Умножьте два массива, мудрый, где один из массивов имеет массивы в виде элементов' имеет пример построения массива из массивов. Если subarrays имеют одинаковый размер, numpy создает 2d-массив. Но если они различаются по длине, он создает массив с dtype=object, а подмассивы сохраняют свою идентичность.

После этого вы можете сделать что-то вроде этого:

In [5]: result=np.array([np.zeros((1)),np.zeros((2))])

In [6]: result
Out[6]: array([array([ 0.]), array([ 0.,  0.])], dtype=object)

In [7]: np.append([result[0]],[1,2])
Out[7]: array([ 0.,  1.,  2.])

In [8]: result[0]
Out[8]: array([ 0.])

In [9]: result[0]=np.append([result[0]],[1,2])

In [10]: result
Out[10]: array([array([ 0.,  1.,  2.]), array([ 0.,  0.])], dtype=object)

Однако я не понимаю, какие преимущества у него есть в чистом списке или списках Python. Он не работает как 2d-массив. Например, я должен использовать result[0][1], а не result[0,1]. Если subarrays имеют одинаковую длину, я должен использовать np.array(result.tolist()) для создания 2d-массива.