Чтение файлов CSV в numpy, где разделитель “”,

У меня есть файл CSV с форматом, который похож на это:

"FieldName1", "FieldName2", "FieldName3", "FieldName4"
"13.04.2010 14:45:07.008", "7.59484916392", "10", "6.552373"
"13.04.2010 14:45:22.010", "6.55478493312", "9", "3.5378543"
...

Обратите внимание, что там удваивают символы кавычки в запуске и конце каждой строки в файле CSV, и "," строка используется для разграничивания полей в каждой строке. Количество полей в файле CSV может варьироваться от файла до файла.

Когда я пытаюсь считать это в numpy через:
import numpy as np
data = np.genfromtxt(csvfile, dtype=None, delimiter=',', names=True)
все данные вкладывают чтение, поскольку строка оценивает, окруженный символами двойной кавычки. Весьма разумный, но не много использования мне, поскольку я затем должен возвратиться и преобразовать каждый столбец в его корректный тип

Когда я использую delimiter='","' вместо этого, все работает, как я хотел бы, за исключением 1-х и последних полей. Поскольку запуск строки и конец символов строки являются единственным символом двойной кавычки, это не рассматривается как допустимый разделитель для 1-х и последних полей, таким образом, они вкладывают чтение как, например. "04/13/2010 14:45:07.008 и 6.552373" - отметьте продвижение и запаздывающие символы двойной кавычки соответственно. Из-за этих избыточных символов numpy предполагает, что 1-ми и последними полями являются оба Строковые типы; я не хочу, чтобы это имело место

Существует ли способ дать numpy команду читать в файлах, отформатированных этим способом, как я хотел бы, не имея необходимость возвращаться и "фиксировать" структуру массива numpy после начального чтения?

9
задан monch1962 18 April 2010 в 15:56
поделиться

1 ответ

Основная проблема в том, что NumPy не понимает концепции удаления кавычек (тогда как модуль csv понимает). Когда вы говорите delimiter = '","' , вы говорите NumPy, что разделитель столбцов - это буквально запятая в кавычках, то есть кавычки вокруг запятой, а не значения, поэтому вы получите дополнительные кавычки на первом и последнем столбцах ожидаются.

Глядя на документацию по функциям, я думаю, что вам нужно установить параметр convertters , чтобы удалить кавычки для вас (по умолчанию нет):

import re
import numpy as np

fieldFilter = re.compile(r'^"?([^"]*)"?$')
def filterTheField(s):
    m = fieldFilter.match(s.strip())
    if m:
        return float(m.group(1))
    else:
        return 0.0 # or whatever default

#...

# Yes, sorry, you have to know the number of columns, since the NumPy docs
# don't say you can specify a default converter for all columns.
convs = dict((col, filterTheField) for col in range(numColumns))
data = np.genfromtxt(csvfile, dtype=None, delimiter=',', names=True, 
    converters=convs)

Или отказаться от np.genfromtxt ( ) и пусть csv.csvreader предоставит вам содержимое файла по строке за раз в виде списков строк, затем вы просто перебираете элементы и строите матрицу:

reader = csv.csvreader(csvfile)
result = np.array([[float(col) for col in row] for row in reader])
# BTW, column headings are in reader.fieldnames at this point.

РЕДАКТИРОВАТЬ: Хорошо, так что похоже, что ваш файл не все плавает. В этом случае вы можете установить convs по мере необходимости в случае genfromtxt или создать вектор функций преобразования в случае csv.csvreader :

reader = csv.csvreader(csvfile)
converters = [datetime, float, int, float]
result = np.array([[conv(col) for col, conv in zip(row, converters)] 
    for row in reader])
# BTW, column headings are in reader.fieldnames at this point.

РЕДАКТИРОВАТЬ 2: Хорошо, количество переменных столбцов ... Ваш источник данных просто хочет усложнить жизнь. К счастью, мы можем просто использовать magic ...

reader = csv.csvreader(csvfile)
result = np.array([[magic(col) for col in row] for row in reader])

... где magic () - это просто название, которое я придумал для функции. (Психея!)

В худшем случае это может быть что-то вроде:

def magic(s):
    if '/' in s:
        return datetime(s)
    elif '.' in s:
        return float(s)
    else:
        return int(s)

Может быть, в NumPy есть функция, которая принимает строку и возвращает единственный элемент правильного типа. numpy.fromstring () выглядит близко, но он может интерпретировать пространство в ваших временных метках как разделитель столбцов.

P.S.Я вижу один недостаток csvreader в том, что он не отбрасывает комментарии; реальные csv файлы не имеют комментариев.

12
ответ дан 3 November 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: