Как создать пустой массив / матрицу в 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)
есть ли способ использовать такую нотацию для включает в себя массивы или матрицы?
9 ответов:
у вас неправильная ментальная модель для эффективного использования 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как имя переменной, вероятно, не очень хорошая практика, так как она маскирует встроенный тип этим именем, что может привести к ошибкам.)EDIT:
если по некоторым причинам вы действительно хотите создать пустой массив, вы можете просто использовать
numpy.array([]), но это редко!
чтобы создать пустой многомерный массив в NumPy (например, 2D массив
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.массив как набор в одном из моих школьных проектов, и мне нужно было инициализировать пустой... Я не нашел никакого подходящего ответа здесь на переполнение стека, поэтому я начал что-то рисовать.
# 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)Я надеюсь, что это помогает.
Вы можете использовать функцию append. Для строк:
>>> 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]])
EDIT
Конечно, как упоминалось в других ответах, если вы не выполняете некоторую обработку (например. инверсия) на матрице / массиве каждый раз, когда вы добавляете что-то к нему, я бы просто создал список, добавил к нему, а затем преобразовал его в массив.
если вы абсолютно не знаете окончательный размер массива, вы можете увеличить размер массива следующим образом:
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').
например, для создания 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)
Comments