NumPy dtype проблемы в genfromtxt(), читает строку в виде bytestring

Я хочу читать в CSV файле standard-ascii в numpy, который состоит из поплавков и строк.

например.

ZINC00043096,C.3,C1,-0.1540,methyl
ZINC00043096,C.3,C2,0.0638,methylene
ZINC00043096,C.3,C4,0.0669,methylene
ZINC00090377,C.3,C7,0.2070,methylene
...

Что бы я ни пытался, результирующий массив выглядел бы как

Например,

all_data = np.genfromtxt(csv_file, dtype=None, delimiter=',')


[(b'ZINC00043096', b'C.3', b'C1', -0.154, b'methyl')
 (b'ZINC00043096', b'C.3', b'C2', 0.0638, b'methylene')
 (b'ZINC00043096', b'C.3', b'C4', 0.0669, b'methylene')

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

Я пробовал несколько вещей из документации numpy.genfromtxt(), например, dtype='S,S,S,f,S' или dtype='a25,a25,a25,f,a25', но здесь ничего не помогло.

Я боюсь, но я думаю, что просто не понимаю, как действительно работает преобразование dtype... Было бы хорошо, если бы вы могли дать мне какой-то намек здесь!

Спасибо

Ответ 1

В Python2.7

array([('ZINC00043096', 'C.3', 'C1', -0.154, 'methyl'),
       ('ZINC00043096', 'C.3', 'C2', 0.0638, 'methylene'),
       ('ZINC00043096', 'C.3', 'C4', 0.0669, 'methylene'),
       ('ZINC00090377', 'C.3', 'C7', 0.207, 'methylene')], 
      dtype=[('f0', 'S12'), ('f1', 'S3'), ('f2', 'S2'), ('f3', '<f8'), ('f4', 'S9')])

в Python3

array([(b'ZINC00043096', b'C.3', b'C1', -0.154, b'methyl'),
       (b'ZINC00043096', b'C.3', b'C2', 0.0638, b'methylene'),
       (b'ZINC00043096', b'C.3', b'C4', 0.0669, b'methylene'),
       (b'ZINC00090377', b'C.3', b'C7', 0.207, b'methylene')], 
      dtype=[('f0', 'S12'), ('f1', 'S3'), ('f2', 'S2'), ('f3', '<f8'), ('f4', 'S9')])

"Регулярные" строки в Python3 являются unicode. Но ваш текстовый файл имеет байтовые строки. all_data в обоих случаях одинаково (136 байтов), но способ отображения строки байтов Python3 - это b'C.3', а не только "C.3".

Какие операции вы планируете выполнять с этими строками? 'ZIN' in all_data['f0'][1] работает с версией 2.7, но в 3 вам нужно использовать b'ZIN' in all_data['f0'][1].

Переменная/неизвестная длина строки /unicode dtype в numpy напоминает, что вы можете указать тип строки в юникоде в dtype. Однако это становится более сложным, если вы заранее не знаете длины строк.

alttype = np.dtype([('f0', 'U12'), ('f1', 'U3'), ('f2', 'U2'), ('f3', '<f8'), ('f4', 'U9')])
all_data_u = np.genfromtxt(csv_file, dtype=alttype, delimiter=',')

производство

array([('ZINC00043096', 'C.3', 'C1', -0.154, 'methyl'),
       ('ZINC00043096', 'C.3', 'C2', 0.0638, 'methylene'),
       ('ZINC00043096', 'C.3', 'C4', 0.0669, 'methylene'),
       ('ZINC00090377', 'C.3', 'C7', 0.207, 'methylene')], 
      dtype=[('f0', '<U12'), ('f1', '<U3'), ('f2', '<U2'), ('f3', '<f8'), ('f4', '<U9')])

В Python2.7 all_data_u отображается как

(u'ZINC00043096', u'C.3', u'C1', -0.154, u'methyl')

all_data_u - 448 байт, потому что numpy выделяет 4 байта для каждого символа юникода. Каждый элемент U4 имеет длину 16 байтов.


Изменения в версии 1.14: https://docs.scipy.org/doc/numpy/release.html#encoding-argument-for-text-io-functions

Ответ 2

np.genfromtxt(csv_file, dtype='|S12', delimiter=',')

Или вы можете выбрать столбцы, которые, как вам известно, являются строками, используя параметр usecols:

np.genfromtxt(csv_file, dtype=None, delimiter=',',usecols=(0,1,2,4))

Ответ 3

В python 3.6,

all_data = np.genfromtxt(csv_file.csv, delimiter=',', dtype='unicode')

отлично работает.