Понимание NumPy dtype "c" со строками - PullRequest
0 голосов
/ 24 октября 2018

Цель: Преобразовать str в np.ndarray из bytes размера 1:

import numpy as np
np.array("abc", dtype=[whatever])

Фактический результат без dtype: array('abc', dtype='<U3')

Желаемый результат: array([b'a', b'b', b'c'], dtype=[whatever] Это позволяет мне использовать нарезку, чтобы получить

Обходной путь, который я нашел, но не понимаю:

np.array("abc", dtype='c')
# array([b'a', b'b', b'c'], dtype='|S1')

Я нашел это методом проб и ошибокдумая, что 'c' может означать 'char'

Что я не понимаю: Почему dtype='c' работает так, как есть?Согласно ссылка на arrays.dtypes 'c' - это сокращение от "комплексная точка с плавающей точкой", тогда как '|S1' - это "байты с нулевым символом в конце (не рекомендуется)" длиной 1.

Также непосредственно используя '| S1' в качестве dtype игнорирует каждый символ, но первый, что не является тем, что я ожидал, но я думаю, что он просто принимает "abc" в качестве одного аргумента и b'a' - это то, что получается, еслитолько один байт указан как dtype:

np.array("abc", dtype='|S1')
# array(b'a', dtype='|S1')

Вопрос (ы):

  1. Почему dtype='c' работает так, как есть?
  2. (Если dtype='c' просто работает "случайно", какой будет "правильный способ" сделать это?)

PS: Да, существует np.chararray , но согласно связанной документации:

Класс chararray существует для обратной совместимости с Numarray, он не рекомендуется для новой разработки.Начиная с numpy 1.4, если нужны массивы строк, рекомендуется использовать массивы dtype object_, string_ или unicode_ и использовать бесплатные функции в модуле numpy.char для быстрых векторизованных строковых операций.

Однако рекомендуемые dtypes object_, string_ и unicode_ не разбивают строку на символы, а возвращают ndarray с одним элементом.

1 Ответ

0 голосов
/ 24 октября 2018

Мне кажется, это ошибка.Обратите внимание, что если вы не укажете количество байтов после кода символа «c», то тип d на самом деле будет «S1», а не комплексной плавающей точкой.Посмотрите на эти атрибуты для dtypes:

>>> dt_S1 = np.dtype('S1')
>>> dt_S1, dt_S1.kind, dt_S1.name, dt_S1.char
(dtype('S1'), 'S', 'bytes8', 'S')

>>> dt_c = np.dtype('c')
>>> dt_c, dt_c.kind, dt_c.name, dt_c.char))
(dtype('S1'), 'S', 'bytes8', 'c')

>>> dt_c8 = np.dtype('c8')
>>> dt_c8, dt_c8.kind, dt_c8.name, dt_c8.char
(dtype('complex64'), 'c', 'complex64', 'F')

Таким образом, можно ожидать, что np.array('abc', dtype='c') и np.array('abc', dtype='S1') вернут тот же результат array(b'a', dtype='S1'), или если первый выдаст ошибку, как если бы np.array('abc', dtype='c8').

Имхо, правильный способ решения вашей задачи:

np.array(list('abc'), dtype='S1')
...