Python Numpy добавляет массив без выравнивания

В Python 3 я импортирую несколько файлов данных в цикле и хотел бы иметь возможность хранить все данные в одном двумерном массиве. Я начинаю с чего-то вроде data = np.array([]) и на каждой итерации я хочу добавить новый массив datai = np.array([1,2,3]), как мне сделать так, чтобы мой окончательный массив выглядел так? [[1,2,3],[1,2,3],...,[1,2,3]]

Я пробовал np.append, np.concatenate и np.stack, но ни один из них не работает. Пример кода, который я пытаюсь:

data = np.array([])
for i in range(datalen):
    datai = *func to load data as array*
    data = np.append(data, datai)

но, конечно, это возвращает сглаженный массив. Есть ли способ вернуть двумерный массив длины datalen, где каждый элемент является массивом datai?

Спасибо!


person Vicente Esnaola    schedule 03.08.2018    source источник
comment
Похоже, вы хотите vstack. Все ли ваши подмассивы одинаковой длины?   -  person user3483203    schedule 03.08.2018
comment
да! Хорошо, я могу заставить это работать для всех итераций после первой, но поскольку я начинаю с пустого массива, это дает мне ошибку измерения. Я могу просто добавить оператор if, чтобы сохранить первый массив, а затем использовать vstack, но есть ли более чистый способ сделать это?   -  person Vicente Esnaola    schedule 03.08.2018
comment
Посмотрите документы np.append. Что там говорится об исключении параметра axis?   -  person hpaulj    schedule 03.08.2018
comment
Вы пытаетесь использовать модель добавления списка для массивов. np.empty([]) не совпадает со списком []. Посмотрите на его shape и ndim. Чтобы concatenate работал, входные данные должны иметь совпадающие размеры. data1 равно 1d (3,). Его можно соединить по оси 0 с другим массивом 1d. Чтобы присоединиться к новой начальной оси, она должна быть 2d (это то, к чему обращается vstack). В любом случае добавление повторного списка - правильный путь, а не повторная конкатенация.   -  person hpaulj    schedule 03.08.2018
comment
Какова форма data1? Как вы его загружаете? Часто при загрузке из txt-файла результирующий массив будет 2d. Это может быть, конечно, 1d.   -  person hpaulj    schedule 03.08.2018
comment
есть ли где-нибудь объяснение этому безумному поведению? (уплощение то есть)   -  person Emile    schedule 07.01.2020


Ответы (5)


Самый быстрый способ - vstack

data = np.vstack((get_data() for i in range(datalen)))

vstack требует tuple/iterable

data = np.vstack((data1, data2, data3))

или вы можете сделать это, добавив ось = 0

data = np.empty(shape=(0, 3))
data = np.append(data, datai.reshape((-1, 3)), axis=0)  # -1 will make the rows automatic
person justengel    schedule 03.08.2018

Решение 1 с использованием списков:

data = []
datalen = 4
datai = range(1,4)
data = [list(datai) for _ in range(datalen)]
print (data)

Выход

[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

Решение 2 (просто немного длинное)

data = []
datalen = 4

for i in range(datalen):
    datai = range(1,4)
    data.append(list(datai))
print (data)  

с тем же выходом, что и выше. Во втором методе вы также можете просто использовать data.append(list(range(1,4))). Вы можете выбрать, хотите ли вы преобразовать datai в список или нет. Если вам нужен окончательный вывод в виде массива, вы можете просто использовать np.array()

person Sheldore    schedule 03.08.2018
comment
метод 2: зачем вызывать np.arange(1,4) вместо range(1,4), если вы все равно собираетесь преобразовать его в список? - person kevinkayaks; 03.08.2018
comment
Хороший улов. Исправлено! Спасибо - person Sheldore; 03.08.2018

Вы можете попробовать это-

data = np.zeros(shape=(datalen,len(datai))
for i in range(datalen):
   data[i] = datai
person Kaustumbh Jaiswal    schedule 03.08.2018
comment
Если вы хотите сделать это с помощью NumPy. - person Kaustumbh Jaiswal; 03.08.2018

Он называется numpy.tile.

Из официальных документов:

>>> c = np.array([1,2,3,4])
>>> np.tile(c,(3,1))
array([[1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4]])

Итак, для вашего datai сделайте np.tile(datai,(N_repeats,1))

person Ufos    schedule 25.06.2020

Вы можете изменить свой массив, используя np.reshape следующим образом

flattened_array = np.array([1,2,3,1,2,3,1,2,3])

wanted_array = np.reshape(flattened_array, (-1, 3))

Это приведет к

[[1, 2, 3],[1, 2, 3],[1, 2, 3]]

person Khaled Khazem    schedule 27.01.2021