Проблема в том, что типы разные. «Title» является частью типа, а y
использует разные имена от x
, поэтому типы несовместимы. Если вы используете совместимые типы, все работает отлично:
>>> x = numpy.array([(1, 2), (3, 4)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> y = numpy.array([(5, 6), (7, 8)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.vstack((x, y))
array([[(1.0, 2.0), (3.0, 4.0)],
[(5.0, 6.0), (7.0, 8.0)]],
dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.hstack((x, y))
array([(1.0, 2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)],
dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.dstack((x, y))
array([[[(1.0, 2.0), (5.0, 6.0)],
[(3.0, 4.0), (7.0, 8.0)]]],
dtype=[('a', '<f4'), ('b', '<f4')])
Иногда dstack
и т.д., достаточно умен, чтобы принуждать типы в разумном пути, но numpy
не имеет никакого способа узнать, как объединить записи массивов с различным определяемым пользователем имена полей.
Если вы хотите объединить типы данных , вам необходимо создать новый тип данных. Не делайте ошибку, думая, что последовательность имен (x['a']
, x['b']
...) представляет собой истинное измерение массива; x
и y
- 1-мерные массивы блоков памяти, каждый из которых содержит два 32-битных поплавка, к которым можно получить доступ, используя имена 'a'
и 'b'
. Но, как вы можете видеть, если вы получаете доступ к отдельному элементу в массиве, вы не получите другого массива, как если бы это было действительно второе измерение. Вы можете увидеть разницу здесь:
>>> x = numpy.array([(1, 2), (3, 4)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> x[0]
(1.0, 2.0)
>>> type(x[0])
<type 'numpy.void'>
>>> z = numpy.array([(1, 2), (3, 4)])
>>> z[0]
array([1, 2])
>>> type(z[0])
<type 'numpy.ndarray'>
Это то, что позволяет массивам записей содержать гетерогенные данные; записи могут содержать как строки, так и ints, но компромисс заключается в том, что вы не получаете полную мощность ndarray
на уровне отдельных записей.
Результат состоит в том, чтобы объединить отдельные блоки памяти, вам действительно нужно изменить размер массива dtype
. Есть несколько способов сделать это, но самый простой я мог бы найти включает малоизвестную numpy.lib.recfunctions
библиотеку (которую я вижу, вы уже нашли!):
>>> numpy.lib.recfunctions.rec_append_fields(x,
y.dtype.names,
[y[n] for n in y.dtype.names])
rec.array([(1.0, 2.0, 1.0, 2.0), (3.0, 4.0, 3.0, 4.0)],
dtype=[('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<f4')])
Но это не то, что я ищу .. Я хочу, чтобы у нового массива были заголовки, унаследованные от объединения ... например после hstack я хочу иметь заголовки: 'a', 'b', 'c', 'd'. Почему python заботится об именах, а не только о типе ?! Сводит меня с ума. Я думаю, что мне нужно использовать Панды, а не просто numpy. –
@HananShteingart, вы используете неправильный подход, тогда вам нужно создать совершенно новый тип данных. Похоже, вы ошибочно полагаете, что 'x' и' y' являются 2-мя массивами. Они не. См. Мои правки выше. – senderle