我有一个包含数组的文件 test.txt:
array = [3,5,6,7,9,6,4,3,2,1,3,4,5,6,7,8,5,3,3,44,5,6,6,7]
现在我要做的是获取数组的内容并使用数组执行一些计算。但问题是当我这样做时,open("test.txt")
它会将内容输出为字符串。实际上数组非常大,如果我做一个循环,它可能效率不高。有什么方法可以在不拆分的情况下获取内容,
?有什么新想法吗?
我建议您将文件另存为 json,然后与json
模块一起读入。要么,要么将其设为 .py 文件,然后将其作为 python 导入。一个看起来像 python 赋值的 .txt 文件有点奇怪。
如果您想在文件中存储类似 python 的表达式,请仅存储表达式(即没有array =
)并使用ast.literal_eval()
.
但是,请考虑使用不同的格式,例如 JSON。根据计算,您可能还需要考虑使用不需要一次将所有数据加载到内存中的格式。
您的文本文件是否需要看起来像 python 语法?逗号分隔值的列表将是提供数据的常用方法:
1,2,3,4,5
csv
然后你可以用上面提到的模块或 numpy 函数读/写。有很多关于如何有效读取 csv 数据的文档。设置好 csv 阅读器数据对象后,可以使用以下方式存储数据:
data = [ map( float, row) for row in csvreader]
数组必须保存为字符串吗?你可以使用一个泡菜文件并将其保存为 Python 列表吗?
如果没有,您可以尝试惰性评估吗?也许只根据需要处理数组的部分。
可能,如果您必须始终对整个数组进行计算,那么最好预先计算这些结果并将它们存储在 txt 文件中,作为列表的补充或代替列表。
您还可以使用 numpy 从使用 numpy.genfromtxt 或 numpy.loadtxt 的文件中加载数据。两者都非常快,并且都能够在加载时进行重铸。如果数组已经加载,您可以使用 numpy 将其转换为浮点数组,这非常快。
import numpy as np
a = np.array(["1", "2", "3", "4"])
a = a.astype(np.float)
你可以写一个解析器。他们非常直截了当。而且比正则表达式快得多,请不要那样做。不是有人建议的。
# open up the file (r = read-only, b = binary)
stream = open("file_full_of_numbers.txt", "rb")
prefix = '' # end of the last chunk
full_number_list = []
# get a chunk of the file at a time
while True:
# just a small 1k chunk
buffer = stream.read(1024)
# no more data is left in the file
if '' == buffer:
break
# delemit this chunk of data by a comma
split_result = buffer.split(",")
# append the end of the last chunk to the first number
split_result[0] = prefix + split_result[0]
# save the end of the buffer (a partial number perhaps) for the next loop
prefix = split_result[-1]
# only work with full results, so skip the last one
numbers = split_result[0:-1]
# do something with the numbers we got (like save it into a full list)
full_number_list += numbers
# now full_number_list contains all the numbers in text format
当缓冲区为空白时,您还必须添加一些逻辑来使用前缀。但我会把代码留给你。
好的,所以以下方法很危险。由于它们用于通过向其中注入代码来攻击系统,因此使用它们需要您自担风险。
array = eval(open("test.txt", 'r').read().strip('array = '))
execfile('test.txt') # this is the fastest but most dangerous.
更安全的方法。
import ast
array = ast.literal_eval(open("test.txt", 'r').read().strip('array = ')).
...
array = [float(value) for value in open('test.txt', 'r').read().strip('array = [').strip('\n]').split(',')]
序列化 python 对象以便稍后加载它们的最简单方法是使用 pickle。假设您不想要人类可读的格式,因为这增加了主要的头部,无论哪种方式,csv 都很快,而 json 很灵活。
import pickle
import random
array = random.sample(range(10**3), 20)
pickle.dump(array, open('test.obj', 'wb'))
loaded_array = pickle.load(open('test.obj', 'rb'))
assert array == loaded_array
pickle 确实有一些开销,如果需要序列化大对象可以指定压缩比,默认为 0 不压缩,可以设置为 pickle.HIGHEST_PROTOCOLpickle.dump(array, open('test.obj', 'wb'), pickle.HIGHEST_PROTOCOL)
如果您正在处理大型数字或科学数据集,则使用 numpy.tofile/numpy.fromfile 或 scipy.io.savemat/scipy.io.loadmat 它们几乎没有开销,但前提是您已经在使用 numpy/scipy。
祝你好运。