Numpy: Объединение структурированных массивов?

вход

У меня многочисленных структурированных массивов в списке, подобном этому примеру:

import numpy a1 = numpy.array([(1, 2), (3, 4), (5, 6)], dtype=[('x', int), ('y', int)]) a2 = numpy.array([(7,10), (8,11), (9,12)], dtype=[('z', int), ('w', float)]) arrays = [a1, a2] 

Желаемый результат

Каков правильный способ объединить их все вместе, чтобы создать единый структурированный массив следующим образом?

 desired_result = numpy.array([(1, 2, 7, 10), (3, 4, 8, 11), (5, 6, 9, 12)], dtype=[('x', int), ('y', int), ('z', int), ('w', float)]) 

Текущий подход

Это то, что я сейчас использую, но это очень медленно, поэтому я подозреваю, что должен быть более эффективный способ.

 from numpy.lib.recfunctions import append_fields def join_struct_arrays(arrays): for array in arrays: try: result = append_fields(result, array.dtype.names, [array[name] for name in array.dtype.names], usemask=False) except NameError: result = array return result 

  • Шрифты Type 1 с лог-диаграммами
  • Скомпилируйте (но не запускайте) скрипт Python
  • Как правильно определить текущий каталог сценариев в Python?
  • Построение кривой с эквидистантными (дуговыми) маркерами
  • Профилирование в Python: кто вызвал функцию?
  • Алгоритм создания (не совсем) набора в Python
  • Печать имен и содержимого переменных в качестве инструмента отладки; ищет emacs / Python ярлык
  • Как проверить, является ли ОС Vista в Python?
  • 3 Solutions collect form web for “Numpy: Объединение структурированных массивов?”

    Вот реализация, которая должна быть быстрее. Он преобразует все в массивы numpy.uint8 и не использует временные numpy.uint8 .

     def join_struct_arrays(arrays): sizes = numpy.array([a.itemsize for a in arrays]) offsets = numpy.r_[0, sizes.cumsum()] n = len(arrays[0]) joint = numpy.empty((n, offsets[-1]), dtype=numpy.uint8) for a, size, offset in zip(arrays, sizes, offsets): joint[:,offset:offset+size] = a.view(numpy.uint8).reshape(n,size) dtype = sum((a.dtype.descr for a in arrays), []) return joint.ravel().view(dtype) 

    Изменить : as_strided() код и избежать ненужного as_strided() .

    Вы также можете использовать функцию merge_arrays numpy.lib.recfunctions :

     import numpy.lib.recfunctions as rfn rfn.merge_arrays(arrays, flatten = True, usemask = False) Out[52]: array([(1, 2, 7, 10.0), (3, 4, 8, 11.0), (5, 6, 9, 12.0)], dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4'), ('w', '<f8')]) 

    и еще один способ, немного более читаемый, а также намного быстрее, я думаю:

     def join_struct_arrays(arrays): newdtype = [] for a in arrays: descr = [] for field in a.dtype.names: (typ, _) = a.dtype.fields[field] descr.append((field, typ)) newdtype.extend(tuple(descr)) newrecarray = np.zeros(len(arrays[0]), dtype = newdtype) for a in arrays: for name in a.dtype.names: newrecarray[name] = a[name] return newrecarray 

    EDIT: с предложениями Sven он становится (немного медленнее, но на самом деле довольно читаемым):

     def join_struct_arrays2(arrays): newdtype = sum((a.dtype.descr for a in arrays), []) newrecarray = np.empty(len(arrays[0]), dtype = newdtype) for a in arrays: for name in a.dtype.names: newrecarray[name] = a[name] return newrecarray 
    Python - лучший язык программирования в мире.