Объединение массивов или массивов списка для вывода данных того же типа в python - PullRequest
1 голос
/ 02 мая 2020

Рассмотрим следующие массивы

import numpy as np
a1 = np.array([1,2,3],dtype='object')
a2 = np.array([["A"],["D"],["R"]],,dtype='object')
a3 = np.array([["A","F"],["D"],["R"]],dtype='object')

Следующие два дают разные типы вывода. Не ожидал этого. Это нормально?

np.c_[a1,a2]

#array([[1, 'A'],
#      [2, 'D'],
#      [3, 'R']], dtype=object)

np.c_[a1,a3]

#array([[1, list(['A', 'F'])],
#      [2, list(['D'])],
#      [3, list(['R'])]], dtype=object)

Почему первое работает, а не второе выражение? Я не вижу никакой разницы между a2 и a3. Кроме того, какой метод конкатенации (c_, стек, конкатенация) будет выводить вывод того же типа без необходимости добавления других строк кода, таких как проверка типа выходных данных и преобразование его по мере необходимости.

np.concatenate((a1,a2),axis=0) # Error: ValueError: all the input arrays must have same number of dimensions

np.concatenate((a1,a3),axis=0) # works
#array([1, 2, 3, list(['A', 'F']), list(['D']), list(['R'])], dtype=object)

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Начиная с numpy do c: В частности, массивы будут размещаться вдоль их последней оси после обновления до, по крайней мере, 2-D с пост-пендом 1. к форме (векторы столбцов, состоящие из одномерных массивов). Это означает, что np.c_ сначала преобразует одномерный массив в двумерный массив, а затем объединяет его вдоль второй оси. Вот что происходит:

В случае np.c_[a1,a2]:

  1. преобразовать a1 в [[1],[2],[3]]
  2. стек [[1],[2],[3]] в [["A"],["D"],["R"]] вдоль второй оси приводит к:

    [[1 'A']
     [2 'D']
     [3 'R']]
    

В случае np.c_[a1,a3]:

  1. преобразовать a1 в [[1],[2],[3]]
  2. Пытается сложить [[1],[2],[3]] до [["A","F"],["D"],["R"]] вдоль второй оси. Однако numpy массивы должны быть прямоугольными angular, а a3 - нет. Альтернатива состоит в том, чтобы интерпретировать каждый список как отдельный элемент и складывать, как показано ниже, чтобы сделать массив прямоугольным angular shape (3,2):

    [[1 list(['A', 'F'])]
     [2 list(['D'])]
     [3 list(['R'])]]
    

В зависимости от того, как вы хотите На выходе быть, есть разные способы. Если вы хотите просто объединить смесь 1D / 2D-массивов в 1D, вы можете сначала squeeze их (удалить размер с размером 1) и объединить так:

np.concatenate((np.squeeze(a1),np.squeeze(a2)),axis=0)
#[1 2 3 'A' 'D' 'R']
np.concatenate((np.squeeze(a1),np.squeeze(a3)),axis=0)
#[1 2 3 list(['A', 'F']) list(['D']) list(['R'])]

Вы также можете hstack их объединить содержимое всех внутренних списков:

np.concatenate((np.hstack(a1),np.hstack(a2)),axis=0)
#[1 2 3 'A' 'D' 'R']
np.concatenate((np.hstack(a1),np.hstack(a3)),axis=0)
#['1' '2' '3' 'A' 'F' 'D' 'R']
1 голос
/ 02 мая 2020

Это действительно имеет смысл, см. Типы каждого из массивов:

a1 = np.array([1,2,3],dtype='object') => 1D array of objects, size 3
a2 = np.array([["A"],["D"],["R"]],,dtype='object') => 2D array of objects, size 3x1
a3 = np.array([["A","F"],["D"],["R"]],dtype='object') => 1D array of lists of objects

a3 - это массив списков, так как np 2d (или более-d) массивы являются матрицами, вы не может иметь 1 строку с размером 1, а вторая с размером 3, большая часть вычислительной эффективности np обусловлена ​​тем, как массивы организованы в памяти.

То есть numpy интерпретирует np.array([["A","F"],["D"],["R"]],dtype='object') как массив списков (которые также являются объектами). Попытка сделать это с другим типом приведет к ошибке:

np.array([[1,2],[3],[4]],dtype=np.int64) -->
ValueError: setting an array element with a sequence.

Поэтому np.concatenate((a1,a2),axis=0) завершится неудачно, поскольку a1 имеет форму (3,), а a2 имеет форму (3,1), в то время как a1 и a3 оба (3,).

Вы можете решить это следующим образом:

np.concatenate((a1,np.reshape(a2,a1.shape)))
np.concatenate((np.reshape(a1,a2.shape),a2))

Оба действительны, у каждого разные результаты, 1 решения не существует, так как объединение между a1 и a2 неоднозначно.

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