Как преобразовать 2D-массив Numpy с объектом dtype в обычный 2D-массив поплавков

Как часть более широкой программы, над которой я работаю, я закончил с массивами объектов со строками, 3D-координатами и т.д. Я знаю, что массивы объектов могут быть не очень любимыми по сравнению со структурированными массивами, но я надеюсь обойти это без изменения большого количества кодов.

Предположим, что каждая строка моего массива obj_array (с N строками) имеет формат

Single entry/object of obj_array:  ['NAME',[10.0,20.0,30.0],....] 

Теперь я пытаюсь загрузить этот массив объектов и отрезать кусок 3D-координаты. До сих пор все работает отлично, просто спрашивая, давайте говорить.

obj_array[:,[1,2,3]]

Однако результат также является массивом объектов, и я столкнусь с проблемой, поскольку я хочу сформировать 2D-массив поплавков с помощью:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates

В настоящее время я перебираю строки и присваиваю каждой строке строке целевого массива 2D-флота, чтобы обойти проблему. Мне интересно, есть ли лучший способ с инструментами преобразования массива numpy? Я пробовал несколько вещей и не мог обойти это.

Centers   = np.zeros([N,3])

for row in range(obj_array.shape[0]):
    Centers[row,:] = obj_array[row,1]

Спасибо

Ответ 1

Неприятная маленькая проблема... Я обманывал этот пример с игрушкой:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
>>> arr
array([['one', [1, 2, 3]],
       ['two', [4, 5, 6]]], dtype=object)

Мое первое предположение:

>>> np.array(arr[:, 1])
array([[1, 2, 3], [4, 5, 6]], dtype=object)

Но это поддерживает dtpe object, поэтому, возможно, тогда:

>>> np.array(arr[:, 1], dtype=np.float)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.

Обычно вы можете обойти это следующим образом:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a readable buffer object

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

>>> np.array([tuple(j) for j in arr[:, 1]],
...          dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

Так как, похоже, не существует абсолютно удовлетворительного решения, проще всего сходить:

>>> np.array(list(arr[:, 1]), dtype=np.float)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

Хотя это будет не очень эффективно, возможно, лучше пойти с чем-то вроде:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3,
...             count=len(arr)).view(np.float).reshape(-1, 3)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])

Ответ 2

На основе примера игрушек Хайме я думаю, что вы можете сделать это очень просто, используя np.vstack():

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object)
float_arr = np.vstack(arr[:, 1]).astype(np.float)

Это будет работать независимо от того, являются ли "числовые" элементы в вашем массиве объектов массивами 1D numpy, списками или кортежами.

Ответ 3

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

x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))])
x[0][0]='item1'
x[1][0]='item2'
y1=x['name']
y2=x['value']

результат:

>>> y1
array(['item1', 'item2'], 
      dtype='|S10')
>>> y2
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]], dtype=float32)

Подробнее: http://docs.scipy.org/doc/numpy/user/basics.rec.html

Ответ 4

Это отлично работает над вашим массивом arr для преобразования из объекта в массив float. После обработки номера очень легко. Спасибо за последнее сообщение!!!! Я просто изменил его, чтобы включить любой размер DataFrame:

float_arr = np.vstack(arr[:, :]).astype(np.float)

Ответ 5

Это способ быстрее преобразовать массив объектов в массив float NumPy: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - оттуда нет цикла, индексируйте его так же, как вы обычно делаете на массиве NumPy. Вы должны были бы сделать это в кусках, но с вашими различными типами данных arr[:, 1], arr[:,2] и т.д. Если бы одна и та же проблема с объектом NumPy tuple возвращалась из С++ DLL-функции - преобразование для 17M элементов занимает < 2s.

Ответ 6

Эта проблема обычно возникает, когда у вас есть набор данных с разными типами, обычно, даты в первом столбце или около того.

То, что я использую, - хранить столбец даты в другой переменной; и взять остальную часть "X-матрицы признаков" в X. Таким образом, у меня есть даты и X, например.

Затем я применяю преобразование к матрице X как:

X = np.array(list(X[:,:]), dtype=np.float)

Надеюсь помочь!