1

我有一个包含数组的文件 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")它会将内容输出为字符串。实际上数组非常大,如果我做一个循环,它可能效率不高。有什么方法可以在不拆分的情况下获取内容,?有什么新想法吗?

4

7 回答 7

9

我建议您将文件另存为 json,然后与json模块一起读入。要么,要么将其设为 .py 文件,然后将其作为 python 导入。一个看起来像 python 赋值的 .txt 文件有点奇怪。

于 2012-06-10T00:34:14.773 回答
5

如果您想在文件中存储类似 python 的表达式,请存储表达式(即没有array =)并使用ast.literal_eval().

但是,请考虑使用不同的格式,例如 JSON。根据计算,您可能还需要考虑使用不需要一次将所有数据加载到内存中的格式。

于 2012-06-10T00:38:42.507 回答
5

您的文本文件是否需要看起来像 python 语法?逗号分隔值的列表将是提供数据的常用方法:

1,2,3,4,5

csv然后你可以用上面提到的模块或 numpy 函数读/写。有很多关于如何有效读取 csv 数据的文档。设置好 csv 阅读器数据对象后,可以使用以下方式存储数据:

data = [ map( float, row) for row in csvreader]
于 2012-06-10T05:25:16.763 回答
2

数组必须保存为字符串吗?你可以使用一个泡菜文件并将其保存为 Python 列表吗?

如果没有,您可以尝试惰性评估吗?也许只根据需要处理数组的部分。

可能,如果您必须始终对整个数组进行计算,那么最好预先计算这些结果并将它们存储在 txt 文件中,作为列表的补充或代替列表。

于 2012-06-10T00:59:38.807 回答
2

您还可以使用 numpy 从使用 numpy.genfromtxt 或 numpy.loadtxt 的文件中加载数据。两者都非常快,并且都能够在加载时进行重铸。如果数组已经加载,您可以使用 numpy 将其转换为浮点数组,这非常快。

import numpy as np
a = np.array(["1", "2", "3", "4"])
a = a.astype(np.float)
于 2012-06-10T02:24:43.307 回答
1

你可以写一个解析器。他们非常直截了当。而且比正则表达式快得多,请不要那样做。不是有人建议的。

# 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

当缓冲区为空白时,您还必须添加一些逻辑来使用前缀。但我会把代码留给你。

于 2012-06-10T01:12:28.387 回答
1

好的,所以以下方法很危险。由于它们用于通过向其中注入代码来攻击系统,因此使用它们需要您自担风险。
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。

祝你好运。

于 2012-06-10T06:38:58.390 回答