Numpy, как добавить имена столбцов в массив Numpy - PullRequest
0 голосов
/ 08 апреля 2019

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

Я пытаюсь добавить имена столбцов в массив Numpy, по сути, превращая его в структурированный массив, хотя все типы данных одинаковы.

Я пытался:

signal = np.array([[1,2,3],[1,2,3],[1,2,3]])
col_names = ('left','right','center')
signal = np.array(signal, dtype = [(n, 'int16') for n in col_names])

, но это возвращает:

array([[(1, 1, 1), (2, 2, 2), (3, 3, 3)],
       [(1, 1, 1), (2, 2, 2), (3, 3, 3)],
       [(1, 1, 1), (2, 2, 2), (3, 3, 3)]],
      dtype=[('left', '<i2'), ('right', '<i2'), ('center', '<i2')])

По сути, у меня есть массив Numpy, представляющий многоканальный сигнал.Я хочу иметь возможность подмножества каналов, используя имена столбцов:

signal['left'] == signal[:,0] # True
signal[['left','center']] == signal[:,[0,2]] # True

Я также видел сообщение, которое кто-то посоветовал не использовать структурированный массив.Есть ли потенциальные недостатки?Скажите, что делает доступ к массиву медленнее?

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Правильная форма ввода данных для структурированного массива - это список кортежей:

In [71]: signal = [(1,2,3),(2,3,1),(3,2,1)] 
    ...: col_names = ('left','right','center') 
    ...: signal = np.array(signal, dtype = [(n, 'int16') for n in col_names])   
In [72]:                                                                        
In [72]: signal                                                                 
Out[72]: 
array([(1, 2, 3), (2, 3, 1), (3, 2, 1)],
      dtype=[('left', '<i2'), ('right', '<i2'), ('center', '<i2')])

1.16 добавил пару функций, которые облегчают преобразование в структурированные массивы и из них:

In [73]: import numpy.lib.recfunctions as rfn                                   
In [74]: signal = np.array([[1,2,3],[1,2,3],[1,2,3]])                           
In [75]: dt = np.dtype([(n, 'int16') for n in col_names])                       
In [76]: dt                                                                     
Out[76]: dtype([('left', '<i2'), ('right', '<i2'), ('center', '<i2')])
In [77]: rfn.unstructured_to_structured(signal, dt)                             
Out[77]: 
array([(1, 2, 3), (1, 2, 3), (1, 2, 3)],
      dtype=[('left', '<i2'), ('right', '<i2'), ('center', '<i2')])

Применение этого dt к signal имеет проблему:

In [82]: signal.view(dt)                                                        
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-82-f0fa01ce8128> in <module>
----> 1 signal.view(dt)

ValueError: When changing to a smaller dtype, its size must be a divisor of the size of original dtype

Мы можем обойти это, сначала преобразовав signal в совместимый тип d:

In [83]: signal.astype('i2').view(dt)                                           
Out[83]: 
array([[(1, 2, 3)],
       [(1, 2, 3)],
       [(1, 2, 3)]],
      dtype=[('left', '<i2'), ('right', '<i2'), ('center', '<i2')])

Но обратите внимание, что Out[83] форма (3,1).Другие массивы были формы (3,).view всегда имел эту проблему формы при преобразовании в / из структурированных массивов.Это одна из причин, почему новые функции проще в использовании.

0 голосов
/ 08 апреля 2019

Вы можете получить правильные результаты, взглянув на

>>> signal.view(dtype=[(n, signal.dtype) for n in col_names])

array([[(1, 2, 3)],
   [(1, 2, 3)],
   [(1, 2, 3)]],
  dtype=[('left', '<i8'), ('right', '<i8'), ('center', '<i8')])

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

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