Я столкнулся со следующей проблемой с NumPy 1.10.2 при чтении файла CSV. Я не могу понять, как передать явные типы данных genfromtxt.

Вот CSV, minimal.csv:

x,y
1,hello
2,hello
3,jello
4,jelly
5,belly

Здесь я пытаюсь прочитать его с помощью

В качестве альтернативы я пробовал:

import numpy
numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)])

Который бросает:

Traceback (most recent call last):
  File "visualize_numpy.py", line 39, in <module>
    numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)])
  File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1834, in genfromtxt
    rows = np.array(data, dtype=[('', _) for _ in dtype_flat])
ValueError: size of tuple must match number of fields.

Я знаю, что dtype=None заставляет NumPy пытаться угадать правильные типы и обычно работает хорошо. Однако в документации упоминается, что это намного медленнее, чем явные типы. В моем случае требуется вычислительная эффективность, поэтому dtype=None не вариант.

Что-то не так с моим подходом или NumPy?

7
Akseli Palén 15 Дек 2015 в 19:42

3 ответа

Лучший ответ

Это хорошо работает и сохраняет информацию вашего заголовка:

df = numpy.genfromtxt('minimal.csv',
                      names=True,
                      dtype=None,
                      delimiter=',')

Это заставляет genfromtxt угадать dtype, который обычно является тем, что вы хотите. Разделитель - это запятая, поэтому мы должны передать этот аргумент и, наконец, names=True сохраняет информацию заголовка.

Просто получите доступ к своим данным, как с любым фреймом:

>>>>print(df['x'])
[1 2 3 4 5]

Изменить . В соответствии с вашим комментарием ниже, вы можете указать dtype явно, например:

df = numpy.genfromtxt('file1.csv',
                      names=True,
                      dtype=[('x', int), ('y', 'S5')], # assuming each string is of len =< 5
                      delimiter=',')
3
N. Wouda 16 Дек 2015 в 17:54

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

Сначала загрузите некоторые данные и проверьте фактические dtypes, которые использует NumPy:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', dtype=None)
>>> movies
array([(1, 'Toy Story (1995)'), (2, 'GoldenEye (1995)'),
       (3, 'Four Rooms (1995)'), ..., (1680, 'Sliding Doors (1998)'),
       (1681, 'You So Crazy (1994)'),
       (1682, 'Scream of Stone (Schrei aus Stein) (1991)')],
      dtype=[('f0', '<i8'), ('f1', 'S81')])

Затем загрузите все ваши данные, используя обнаруженные типы:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', 
                           dtype=[('f0', '<i8'), ('f1', 'S81')]) 

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

0
gwg 14 Ноя 2016 в 23:19

Из краткого взгляда на документацию, по умолчанию delimiter=None.

Попробуйте numpy.genfromtxt('minimal.csv', dtype=(int, str), names=True, delimiter=',')

0
pushkin 16 Дек 2015 в 01:24