Самый быстрый способ чтения файлов через запятую (включая datetime) в python - PullRequest
2 голосов
/ 07 марта 2011

У меня есть данные, хранящиеся в текстовых файлах с разделителями-запятыми.Один из столбцов представляет дату и время.

Мне нужно загрузить каждый столбец в отдельные массивы (и декодировать дату в объект datetime Python).

Какой самый быстрый способ сделать это(с точки зрения времени выполнения)?

Примечание.файлы содержат несколько сотен МБ данных и в настоящее время загружаются в течение нескольких минут.

например, mydata.txt

15,3,0,2003-01-01 00:00:00,12.2
15,4.5,0,2003-01-01 00:00:00,13.7
15,6,0,2003-01-01 00:00:00,18.4
15,7.5,0,2003-01-01 00:00:00,17.9
15,9,0,2003-01-01 00:00:00,17.7
15,10.5,0,2003-01-01 00:00:00,16.3
15,12,0,2003-01-01 00:00:00,17.2

Вот мой текущий код (работает, но медленно):

import csv
import datetime
import time
import numpy

a=[]
b=[]
c=[]
d=[]
timestmp=[]

myfile = open('mydata.txt',"r")

# Read in the data
csv_reader = csv.reader(myfile)
for row in csv_reader:
  a.append(row[0])
  b.append(row[1])
  c.append(row[2])
  timestmp.append(row[3])
  d.append(row[4])

a = numpy.array(a)
b = numpy.array(b)
c = numpy.array(c)
d = numpy.array(d)

# Convert Time string list into list of Python datetime objects
times = []
time_format = "%Y-%m-%d %H:%M:%S"
for i in xrange(len(timestmp)):
  times.append(datetime.datetime.fromtimestamp(time.mktime(time.strptime(timestmp[i], time_format))))

Есть ли более эффективный способ сделать это?

Любая помощь очень ценится - спасибо!

(редактировать: В конце концов,Оказалось, что узким местом является преобразование даты и времени, а не чтение файла, как я изначально предполагал.)

Ответы [ 5 ]

8 голосов
/ 07 марта 2011

Во-первых, вы должны запустить ваш пример скрипта со встроенным в Python profiler , чтобы увидеть, где на самом деле может быть проблема.Вы можете сделать это из командной строки:

python -m cProfile myscript.py

Во-вторых, что по крайней мере прыгает на меня, зачем нужен этот цикл внизу?Есть ли техническая причина, по которой это невозможно сделать при чтении mydata.txt в цикле, который вы имеете над созданием экземпляров numpy массивов?

В-третьих, вы должны создавать объекты datetime напрямую, так как он также поддерживаетstrptime.Вам не нужно создавать метку времени, делать время и просто делать дату и время из метки времени.Ваш цикл внизу можно просто переписать так:

times = []
timestamps = []
TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
for t in timestmp:
    parsed_time = datetime.datetime.strptime(t, TIME_FORMAT)
    times.append(parsed_time)
    timestamps.append(time.mktime(parsed_time.timetuple()))

Я тоже немного свободен в PEP-8, добавляя ваш код, например, изменяя вашу константу на все заглавные буквы.Кроме того, вы можете перебирать список, просто используя оператор in.

3 голосов
/ 07 марта 2011

Попробуйте numpy.loadtxt(), хороший пример - строка doc .

2 голосов
/ 07 марта 2011

Вы также можете попытаться использовать copy=False при вызове numpy.array, поскольку по умолчанию используется его копирование, это может ускорить выполнение сценария (особенно если вы сказали, что он обрабатывает много данных).

npa = numpy.array(ar, copy=False)
1 голос
/ 07 марта 2011

Я не совсем уверен, поможет ли это, но вы можете ускорить чтение файла, используя ast.literal_eval. Например:

from ast import literal_eval

myfile = open('mydata.txt',"r")
mylist = []
for line in myfile:
    line = line.strip()
    e = line.rindex(",")
    row = literal_eval('[%s"%s"%s]' % (line[:e-19], line[e-19:e], line[e:]))
    mylist.append(row)

a, b, c, timestamp, d = zip(*mylist)
# a, b, c, timestamp, and d are what they were after your csv_reader loop
1 голос
/ 07 марта 2011

Если вы последуете совету Махмуда Абделькадера и используете профилировщик и обнаружите, что узкое место в загрузчике csv, вы всегда можете попробовать заменить ваш csv_reader следующим:

for line in open("ProgToDo.txt"):
  row = line.split(',')
  a.append(int(row[0]))
  b.append(int(row[1]))
  c.append(int(row[2]))
  timestmp.append(row[3])
  d.append(float(row[4]))

Но более вероятно, я думаю, что у вас есть много преобразований данных. Особенно последний цикл преобразования времени займет много времени, если у вас есть миллионы преобразований! Если вам удастся сделать все это за один шаг (чтение + преобразование), а также прислушаться к советам Terseus о том, что не следует копировать массивы в numy dittos, вы сократите время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...