Использование numpy.genfromtxt для чтения csv файла со строками, содержащими запятые
Я пытаюсь читать в csv файле с numpy.genfromtxt
, но некоторые из полей - это строки, содержащие запятые. Строки находятся в кавычках, но numpy не распознает кавычки как определяющие одну строку. Например, с данными в 't.csv':
2012, "Louisville KY", 3.5
2011, "Lexington, KY", 4.0
код
np.genfromtxt('t.csv', delimiter=',')
вызывает ошибку:
ValueError: обнаружены некоторые ошибки! Строка №2 (получилось 4 столбца вместо 3)
Структура данных, которую я ищу, это:
array([['2012', 'Louisville KY', '3.5'],
['2011', 'Lexington, KY', '4.0']],
dtype='|S13')
Оглядываясь на документацию, я не вижу никаких вариантов решения этой проблемы. Есть ли способ сделать это с numpy, или мне просто нужно читать данные с помощью модуля csv
, а затем преобразовать его в массив numpy?
Ответы
Ответ 1
Вы можете использовать pandas (для этого используется библиотека по умолчанию для работы с фреймами данных (гетерогенных данных) в научном python). Это read_csv
может справиться с этим. Из документов:
quotechar: string
The character to used to denote the start and end of a quoted item. Quoted items
can include the delimiter and it will be ignored.
Значение по умолчанию "
. Пример:
In [1]: import pandas as pd
In [2]: from StringIO import StringIO
In [3]: s="""year, city, value
...: 2012, "Louisville KY", 3.5
...: 2011, "Lexington, KY", 4.0"""
In [4]: pd.read_csv(StringIO(s), quotechar='"', skipinitialspace=True)
Out[4]:
year city value
0 2012 Louisville KY 3.5
1 2011 Lexington, KY 4.0
Трюк здесь в том, что вам также нужно использовать skipinitialspace=True
для работы с пробелами после разделителя запятой.
Помимо мощного считывателя csv, я также могу настоятельно рекомендовать использовать pandas с гетерогенными данными, которые у вас есть (пример вывода в numpy, который вы указываете, это все строки, хотя вы можете использовать структурированные массивы).
Ответ 2
Проблема с дополнительной запятой np.genfromtxt
не связана с этим.
Одно простое решение - прочитать файл с csv.reader()
из модуля python csv в список, а затем сбросить его в numpy массив, если хотите.
Если вы действительно хотите использовать np.genfromtxt
, обратите внимание, что он может принимать итераторы вместо файлов, например. np.genfromtxt(my_iterator, ...)
. Итак, вы можете обернуть csv.reader
в итераторе и передать его np.genfromtxt
.
Это будет выглядеть примерно так:
import csv
import numpy as np
np.genfromtxt(("\t".join(i) for i in csv.reader(open('myfile.csv'))), delimiter="\t")
Это существенно заменяет на лету только соответствующие запятые с вкладками.
Ответ 3
Если вы используете numpy, вы, вероятно, захотите работать с numpy.ndarray. Это даст вам numpy.ndarray:
import pandas
data = pandas.read_csv('file.csv').as_matrix()
Pandas будет корректно обрабатывать случай "Лексингтон, KY"
Ответ 4
Сделайте лучшую функцию, которая сочетает в себе мощность стандартного csv
module и Numpy recfromcsv
. Например, модуль csv
имеет хороший контроль и настройку диалектов, кавычек, escape-символов и т.д., Которые вы можете добавить к приведенному ниже примеру.
Ниже приведен пример функции genfromcsv_mod
в сложном файле CSV, аналогичном тому, что видит Microsoft Excel, который может содержать запятые в указанных полях. Внутренне функция имеет функцию генератора, которая переписывает каждую строку с разделителями табуляции.
import csv
import numpy as np
def recfromcsv_mod(fname, **kwargs):
def rewrite_csv_as_tab(fname):
with open(fname, 'rb') as fp:
reader = csv.reader(fp)
for row in reader:
yield '\t'.join(row)
return np.recfromcsv(rewrite_csv_as_tab(fname), delimiter='\t', **kwargs)
# Use it to read a CSV file into a record array
x = recfromcsv_mod('t.csv', case_sensitive=True)