У меня есть несколько текстовых файлов, скажем, 50, что мне нужно прочитать в массивный фреймворк. На данный момент я использую следующие шаги.
- Прочитайте каждый файл и проверьте, что такое метки. Информация, которая мне нужна, часто содержится в первых нескольких строках. Те же ярлыки просто повторяются для остальной части файла, причем каждый раз каждый из них имеет разные типы данных.
- Создайте фрейм с этими метками.
- Снова прочитайте файл и заполните dataframe со значениями.
- Объединить этот фрейм данных с основным фреймворком данных.
Это очень хорошо подходит для файлов размером 100 КБ - несколько минут, но при 50 МБ это занимает всего несколько часов, и это не практично.
Как я могу оптимизировать свой код? В частности -
- Как определить, какие функции занимают больше всего времени, которые мне нужно оптимизировать? Это чтение файла? Это запись в dataframe? Где моя программа тратит время?
- Должен ли я рассматривать многопоточность или многопроцессорность?
- Могу ли я улучшить алгоритм?
- Возможно, прочитайте весь файл за один раз в списке, а не за строкой,
- Разбирать данные в кусках/весь файл, а не по строкам,
- Назначить данные в кадр данных в кусках/один раз, а не в строке за строкой.
- Есть ли что-нибудь еще, что я могу сделать, чтобы сделать мой код быстрее?
Вот пример кода. Мой собственный код немного сложнее, поскольку текстовые файлы более сложны, так что я должен использовать около 10 регулярных выражений и несколько циклов while для считывания данных и размещения их в нужном месте в правильном массиве. Чтобы поддерживать MWE просто, я не использовал повторные метки во входных файлах для MWE, поэтому мне хотелось бы, чтобы я дважды читал файл без причины. Надеюсь, это имеет смысл!
import re
import pandas as pd
df = pd.DataFrame()
paths = ["../gitignore/test1.txt", "../gitignore/test2.txt"]
reg_ex = re.compile('^(.+) (.+)\n')
# read all files to determine what indices are available
for path in paths:
file_obj = open(path, 'r')
print file_obj.readlines()
['a 1\n', 'b 2\n', 'end']
['c 3\n', 'd 4\n', 'end']
indices = []
for path in paths:
index = []
with open(path, 'r') as file_obj:
line = True
while line:
try:
line = file_obj.readline()
match = reg_ex.match(line)
index += match.group(1)
except AttributeError:
pass
indices.append(index)
# read files again and put data into a master dataframe
for path, index in zip(paths, indices):
subset_df = pd.DataFrame(index=index, columns=["Number"])
with open(path, 'r') as file_obj:
line = True
while line:
try:
line = file_obj.readline()
match = reg_ex.match(line)
subset_df.loc[[match.group(1)]] = match.group(2)
except AttributeError:
pass
df = pd.concat([df, subset_df]).sort_index()
print df
Number
a 1
b 2
c 3
d 4
Мои входные файлы:
test1.txt
a 1
b 2
end
test2.txt
c 3
d 4
end