Как добавить список примитивов в массив объектов - PullRequest
0 голосов
/ 06 июля 2018

РЕДАКТИРОВАТЬ: я получил много полезных отзывов о том, как не сделать это и как найти альтернативы, но что делает это полезным, зависит от особенностей моего варианта использования, которые могут сделать этот вопрос менее полезным другим. На данный момент, Я не ищу альтернативы использованию данных, структурированных как это . Я ищу , почему кажется невозможным сделать это в numpy (или как это сделать, если это не невозможно)

У меня есть массив numpy, который выглядит как

a = array([list([1]), list([4, 5])], dtype=object)

Я хочу добавить список вроде

b = [2, 3, 4]

Чтобы получить результат как

array([list([1]), list([4, 5]), list([2, 3, 4])], dtype=object)

Однако, каждый метод, который я пробовал, произвел:

array([list([1]), list([4, 5]), 2, 3, 4], dtype=object)

Я пробовал vstack, объединять и добавлять, а также упаковывать объекты в списки или ndarrays.

Почему я это делаю? По сути, у меня есть много данных в ndarray, которые будут загружены в sklearn. Я хочу иметь 3d ndarray (наборы данных x точки данных x особенности), но входящие данные плохие и некоторые вещи имеют разную длину, поэтому самым внутренним измерением должны быть списки. Я пытаюсь добавить производную функцию, которая не работает. Мне удалось изменить порядок операций, чтобы избежать необходимости добавлять это, но я все еще хочу знать, как это сделать. Это кажется странным провалом для NumPy. edit: Короче говоря, внешний массив должен быть ndarray , потому что он на самом деле 2d, и часто используется сложное нарезание, в то время как операция добавления происходит очень мало раз.

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Присоединение к массиву - это, в первую очередь, дорогая и вонючая операция. Дело в том, что содержимое массива может быть изменяемым, а адрес базового буфера - нет. Каждый раз, когда вы добавляете элемент, все это перераспределяется и копируется. Насколько я знаю, нет даже попытки амортизации, как с list.

Если вы придерживаетесь немного другого подхода, я бы порекомендовал сохранить ваши данные в list, как у вас сейчас. Вы просто преобразуете свой список в массив, когда вам действительно нужен массив. Помните, что это дешевле, чем каждый раз перераспределять новый массив, и вам, вероятно, не придется делать это часто по сравнению с количеством добавлений:

stack = [[1], [4, 5]]
a = np.array(stack, dtype=np.object)
# do stuff to the array

...

stack.append([2, 3, 4])
a = np.array(stack, dtype=np.object)

Обновление Теперь, когда я понял ваш вопрос

Если ваша цель состоит в том, чтобы просто выяснить, как добавить элемент в массив объектов, не имея при этом факта, что это список, вам нужно сначала создать массив или элемент, который будет пустым. Вместо того, чтобы пытаться принудить тип с помощью поддельных элементов, как предлагают некоторые комментарии, я рекомендую просто создать пустые элементы и явно указать их в своем списке. Вы можете заключить операцию в функцию, если хотите иметь чистый интерфейс.

Вот пример:

b = [2, 3, 4]
c = np.empty(1, dtype=np.object)
c[0] = b
a = np.concatenate((a, c))

OR

a = np.append(a, c)

Конечно, это не так чисто, как np.array([b], dtype=np.object), но это всего лишь артефакт того, как массивные процессы обрабатывают массивы. Причина, по которой вам в значительной степени приходится делать это так, заключается в том, что numpy рассматривает все, что является списком или кортежем, как специальный элемент, который вы хотите преобразовать в массив на внешнем уровне.

0 голосов
/ 06 июля 2018

Если вам действительно нужно иметь np.ndarray с dtype=object, вы можете сделать это:

a = np.array([list([1]), list([4, 5])], dtype=object)
b = [2, 3, 4]
a = np.hstack((a, np.empty(1)))
a[-1] = b

(или, конечно, удалить np. в вашем случае, когда вы полностью импортировали numpy.)
Но я рекомендую не использовать np.ndarray с dtype=object. Вместо этого используйте list s с:

a = [[list([1]), list([4, 5])]]
b = [2, 3, 4]
a.append(b)

Теперь, если вы действительно хотите иметь a в качестве np.ndarray, вы можете сделать следующее:

a = np.array(a)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...