Как заставить numpy.genfromtxt генерировать неструктурированный массив numpy? - PullRequest
1 голос
/ 20 октября 2019

В Python 3 я делаю:

s = StringIO(u"1,1.3,abcde\n2,1.3,test")
data = numpy.genfromtxt(s, dtype=[int,float,'U10'], delimiter=',', names=None)

и получаю:

array([(1, 1.3, 'abcde'), (2, 1.3, 'test')],
      dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U10')])

Я хотел бы получить обычный массив numpy без имен, как показано ниже:

array([[1, 1.3, 'abcde'], 
        [2, 1.3, 'test']])

Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

С текстовым списком:

In [338]: txt = '''1, 1.3, abcde 
     ...: 2, 1.3, def'''.splitlines()                                           

Структурированный массив:

In [339]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)          
Out[339]: 
array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
      dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])

Попытка указать объект - каждый элемент имеет свой тип:

In [340]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None)        
Out[340]: 
array([[b'1', b' 1.3', b' abcde'],
       [b'2', b' 1.3', b' def']], dtype=object)

Он не пытается преобразовать строки в числа.

converters преобразует столбцы правильно, но по какой-то причине все еще создает структурированный массив:

In [341]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None, convert
     ...: ers={0:int, 1:float})                                                 
Out[341]: 
array([(1, 1.3, b' abcde'), (2, 1.3, b' def')],
      dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', 'O')])

Но вы можете преобразовать структурированный массивмассив к объекту dtype через список:

In [346]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)          
Out[346]: 
array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
      dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])
In [347]: np.array(_.tolist(), object)                                          
Out[347]: 
array([[1, 1.3, ' abcde'],
       [2, 1.3, ' def']], dtype=object)

Другой вариант - разделить строки самостоятельно, создав список списков. genfromtxt делает это с небольшим количеством наворотов.

In [357]: lines=[] 
     ...: for line in txt: 
     ...:     i = line.split(',') 
     ...:     x = (int(i[0]), float(i[1]), i[2].strip()) 
     ...:     lines.append(x) 

In [358]: lines                                                                 
Out[358]: [(1, 1.3, 'abcde'), (2, 1.3, 'def')]
In [359]: np.array(lines,object)                                                
Out[359]: 
array([[1, 1.3, 'abcde'],
       [2, 1.3, 'def']], dtype=object)

Но учтите, что вы не можете выполнять математику для этого массива объектов, а также для числового массива или даже числовых полейструктурированный массив.

0 голосов
/ 20 октября 2019

То, что вы получили, это «структурированный массив», и он превосходит «обычный массив», потому что он поддерживает гетерогенные типы данных. Два ваших столбца - это числа, но один - текст, поэтому на самом деле не имеет смысла сворачивать ваши данные в простой numpy.ndarray без структуры. Но если вы хотите, вы можете:

numpy.array(data.tolist())

Это даст вам ndarray со всеми строками:

array([['1', '1.3', 'abcde'],
       ['2', '1.3', 'test']], dtype='<U32')

Но это редко хорошая идея. Если бы у нас было больше контекста, мы могли бы предложить лучший общий подход.

...