【发布时间】:2017-06-28 17:12:02
【问题描述】:
我有许多文本文件,比如 50 个,我需要将它们读入一个庞大的数据框。目前,我正在使用以下步骤。
- 阅读每个文件并检查标签是什么。我需要的信息通常包含在前几行中。相同的标签只是在文件的其余部分重复,每次都列出不同类型的数据。
- 使用这些标签创建一个数据框。
- 再次读取文件并用值填充数据框。
- 将该数据帧与主数据帧连接起来。
这对于 100 KB 大小的文件非常有效 - 几分钟,但在 50 MB 时,只需要几个小时,而且不实用。
如何优化我的代码?特别是-
- 如何确定哪些功能花费的时间最多,我需要优化哪些功能?是文件的读取吗?是写入数据框吗?我的计划在哪里花费时间?
- 我应该考虑多线程还是多处理?
- 我可以改进算法吗?
- 也许将整个文件一次读入一个列表,而不是逐行读取,
- 在块/整个文件中解析数据,而不是逐行解析,
- 一次性将数据分配给数据帧,而不是逐行。
- 我还能做些什么来让我的代码执行得更快吗?
这是一个示例代码。我自己的代码稍微复杂一些,因为文本文件更复杂,以至于我必须使用大约 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
【问题讨论】:
-
可能会得到更快的磁盘:)
-
同时,查找一个好的 Python 分析器。这是一个通用类的工具,它会告诉你程序的哪一部分是瓶颈。
-
您不能读取数据框中的全部 50 个文件,然后运行基于正则表达式的操作吗?这会很快,因为对 pandas 的过滤操作非常快......
标签: python regex performance parsing pandas