Как мне создать пустой массив / матрицу в NumPy?
Вопрос
Я не могу понять, как использовать массив или матрицу так, как я обычно использую список.Я хочу создать пустой массив (или матрицу), а затем добавлять к нему по одному столбцу (или строке) за раз.
На данный момент единственный способ, который я могу найти для этого, это:
mat = None
for col in columns:
if mat is None:
mat = col
else:
mat = hstack((mat, col))
В то время как если бы это был список, я бы сделал что-то вроде этого:
list = []
for item in data:
list.append(item)
Есть ли способ использовать такого рода обозначения для NumPy массивы или матрицы?
Решение
У вас неправильная ментальная модель для эффективного использования NumPy.Массивы NumPy хранятся в смежных блоках памяти.Если вы хотите добавить строки или столбцы в существующий массив, весь массив необходимо скопировать в новый блок памяти, создав пробелы для сохранения новых элементов.Это очень неэффективно, если выполнять это многократно для построения массива.
В случае добавления строк лучше всего создать массив такого размера, каким в конечном итоге будет ваш набор данных, а затем добавлять в него данные построчно:
>>> 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.]])
Другие советы
Массив NumPy - это структура данных, сильно отличающаяся от списка, и предназначена для использования различными способами.Ваше использование hstack
потенциально это очень неэффективно...каждый раз, когда вы вызываете его, все данные из существующего массива копируются в новый.(Тот append
функция столкнется с той же проблемой.) Если вы хотите создавать свою матрицу по одному столбцу за раз, возможно, вам лучше всего сохранить ее в списке до тех пор, пока она не будет завершена, и только после этого преобразовать ее в массив.
например ,
mylist = []
for item in data:
mylist.append(item)
mat = numpy.array(mylist)
item
может быть списком, массивом или любым итерируемым, до тех пор, пока
поскольку каждый item
имеет такое же количество элементов.
В данном конкретном случае (data
является ли некоторый итерируемый, содержащий столбцы матрицы), вы можете просто использовать
mat = numpy.array(data)
(Также обратите внимание, что использование list
поскольку имя переменной, вероятно, не является хорошей практикой, поскольку оно маскирует встроенный тип этим именем, что может привести к ошибкам.)
Редактировать:
Если по какой-то причине вы действительно хотите создать пустой массив, вы можете просто использовать numpy.array([])
, но это редко бывает полезно!
Чтобы создать пустой многомерный массив в NumPy (напримердвумерный массив m*n
для хранения вашей матрицы), на случай, если вы не знаете m
сколько строк вы добавите и не заботитесь о вычислительных затратах, упомянутых Стивеном Симмонсом (а именно о повторном создании массива при каждом добавлении), вы можете сжать до 0 измерение, к которому вы хотите добавить: X = np.empty(shape=[0, n])
.
Таким образом, вы можете использовать, например (здесь m = 5
который, как мы предполагаем, мы не знали при создании пустой матрицы, и 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
который даст вам:
[[ 0. 0.]
[ 0. 1.]
[ 1. 0.]
[ 1. 1.]
[ 2. 0.]
[ 2. 1.]
[ 3. 0.]
[ 3. 1.]
[ 4. 0.]
[ 4. 1.]]
Я много изучал это, потому что мне нужно было использовать numpy.array в качестве набора в одном из моих школьных проектов, и мне нужно было инициализировать его пустым...Я не нашел здесь никакого релевантного ответа о переполнении стека, поэтому я начал что-то рисовать.
# 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)
Результатом будет:
In [34]: x
Out[34]: array([], dtype=float64)
Следовательно, вы можете непосредственно инициализировать np-массив следующим образом:
In [36]: x= np.array([], dtype=np.float64)
Я надеюсь, что это поможет.
Вы можете использовать функцию добавления.Для строк:
>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],
[1, 2, 3]])
Для столбцов:
>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],
[1, 2, 3, 15]])
Редактировать
Конечно, как упоминалось в других ответах, если только вы не выполняете некоторую обработку (напр.инверсия) в матрице / массиве КАЖДЫЙ раз, когда вы добавляете к ней что-то, я бы просто создавал список, добавлял к нему, а затем преобразовывал его в массив.
Если вы абсолютно не знаете конечный размер массива, вы можете увеличить размер массива следующим образом:
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.]]
- Обратите внимание на
0
в первой строке. numpy.append
есть еще один вариант.Это вызываетnumpy.concatenate
.
Вы можете применить его для построения любого вида массива, например нулей:
a = range(5)
a = [i*0 for i in a]
print a
[0, 0, 0, 0, 0]
В зависимости от того, для чего вы это используете, вам может потребоваться указать тип данных (см. "dtype" (тип dtype)).
Например, для создания 2D-массива из 8-битных значений (пригодного для использования в качестве монохромного изображения):
myarray = numpy.empty(shape=(H,W),dtype='u1')
Для изображения RGB укажите количество цветовых каналов в форме: shape=(H,W,3)
Вы также можете рассмотреть возможность инициализации нулем с помощью numpy.zeros
вместо того, чтобы использовать numpy.empty
.Смотрите заметку здесь.
Я думаю, вы хотите выполнить большую часть работы со списками, а затем использовать результат в виде матрицы.Может быть, это и есть способ ;
ur_list = []
for col in columns:
ur_list.append(list(col))
mat = np.matrix(ur_list)
Я думаю, вы можете создать пустой массив numpy, например:
>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)
Этот формат полезен, когда вы хотите добавить массив numpy в цикле.