У меня есть файл 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 после начального чтения?
Основная проблема в том, что 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
файлы не имеют комментариев.