короткий ответ:
csv reader
и haraprasadj
(см ответ ниже) практически идентичны по скорости.
Длинный ответ:
Я попробовал все предложенные методы, будучи numpy.genfromtxt()
, код haraprasadj предложил, и я возился с моей power_read()
функции следующим образом:
def power_read(fhandle, identifiers):
findme = '(?<=%s\W)[0-9.]+' %identifiers[0]
result = np.zeros(10000)
cnt = 0
ALL = fhandle.read()
fhandle.close()
found = re.findall(findme, ALL, flags=re.S)
for f in found:
result[cnt] = float(f)
return result[0:cnt]
Почему это изменение? Я понял, что, по всей видимости, это мудрая расследование занимает гораздо больше времени. Версия для вопросов - 18 с, комбинированная для 10 запусков, а версия выше - всего 6 секунд.
numpy.genfromtxt(fhandle, delimiter='\t',
dtype={'names':('Time', 'Identifier', 'Value'),
'formats':('datetime64[ns]', 'S50', 'f8')})
В той же установке используется около 41 секунды и дисквалифицируется.
Далее я оценивал среднее значение более 50 трасс и результат заключается в следующем:
- нового
power_read
: 0,582 с
haraprasadj
: 1,033 с
readfile
: 1.081 s
В то время как решение re
выглядит как победитель в данный момент, оно по-прежнему не считывает сразу несколько Идентификаторов. Кроме того, csv читает временные метки. Теперь я буду исследовать, как можно обрабатывать несколько ключевых слов и как это влияет на время выполнения. Кроме того, при полном чтении в одном необходимо всегда учитывать ограничения памяти.
Следующий шаг с функцией power_read()
было то, что я добавил еще некоторые функциональные возможности, включая извлечение метки времени и поддержку нескольких ключевых слов, возвращая удобный словарь:
def power_read(fhandle, identifiers):
ALL = fhandle.read()
fhandle.close()
result = {}
for i in identifiers:
findme = ('(?P<timestamp>\d+-\d+-\d+ \d+:\d+:\d+.[\d\+]+)\W%s\W(?P<value>[\d.]+)' %i)
res = np.empty(shape=(10000, 2), dtype=[('time','datetime64[ns]'), ('value','f4')])
cnt = 0
found = re.findall(findme, ALL, flags=re.S)
for f in found:
res[cnt] = np.array(f, dtype=[('time','datetime64[ns]'), ('value','f4')])
result[i] = res[0:cnt,:]
return result
я тестировал с 1 ключевым словом и 3 ключевыми словами:
read_file
1kword = 1.1s 3kword = 1.1s
haraprasadj
1kword = 1.0с 3kword = 1.1s
power_read
1kword = 1.4s 3kword = 4.2s
резюмировать, если один только не стремится извлечь только одно значение для чтения CSV и метод haraprasadj кажутся выше. Тем не менее, пока еще не было выбора для двух верхних методов. У кого-то есть хорошая идея, как эффективно вывести результаты? Для того, чтобы исследовать, я изменил методы следующим образом и вызывается с тремя ключевыми словами:
def read_file(fhandle, identifiers, dialect):
csvr = csv.reader(fhandle, dialect)
data = []
EOF = False
while not EOF:
try:
row=csvr.next()
if row[2] in identifiers:
data.append(tuple(row[1:-1]))
except StopIteration:
EOF = True
fhandle.close()
data = np.array(data, dtype=None)
time = data[:,0]
ids = data[:,1]
value = data[:,2]
res = {}
for i in identifiers:
msk = np.where(ids==i, True, False)
res[i] = np.array(zip(time[msk], value[msk]), dtype=[('time','datetime64[us]'), ('value','f8')])
return res
и второй функции, оптимизированы для точных данных, что имею дело с:
def haraprasadj(fhandle, identifiers):
data = [line.strip().split('\t')[1:] for line in fhandle.readlines()]
fhandle.close()
result = np.array(filter(lambda x:x[1] in identifiers, data))
time =result[:,0]
ids = result[:,1]
value = result[:,2]
res = {}
for i in identifiers:
msk = np.where(ids==i, True, False)
res[i] = np.array(zip(time[msk], value[msk]), dtype=[('time','datetime64[us]'), ('value','f8')])
return res
Оказывается, что оба подходы примерно с одинаковой скоростью (по крайней мере, для моего тестового размера файла):
read_file()
1,12 s
haraprasadj
1.06 s
Сравнение с предыдущими результатами показывает, что приведение типов требует лишь незначительное количество времени, что было для меня неожиданным.
Оставшаяся разница в том, что haraprasadj
занимает больше памяти, что может быть важно для некоторых приложений. Для удобства чтения я поеду с моим оригинальным файлом read_file(), и теперь начну смотреть на параллельные вычисления.
Вы пробовали 'numpy.loadtxt()' или 'numpy.genfromtxt()'? – Anton
Я только что попробовал 'loadtxt' и' genfromtxt'. Я не мог использовать 'loadtxt()', потому что, по-видимому, некоторые отсутствующие значения, поэтому я переключился на 'genfromtxt()'. Очень медленно. – Faultier
Другой ответ предполагает, что 'pandas.read_csv()' работает быстро: http://softwarerecs.stackexchange.com/questions/7463/fastest-python-library-to-read-a-csv-file – Anton