首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内存上限?

内存上限?
EN

Stack Overflow用户
提问于 2010-11-26 12:11:09
回答 5查看 155.8K关注 0票数 31

对于python来说,内存有限制吗?我一直在使用python脚本来计算文件的平均值,该文件至少有150 of大。

根据文件的大小,我有时会遇到一个MemoryError

能给python分配更多的内存吗?这样我就不会遇到错误了?

编辑:下面的代码

注意:文件大小差异很大(高达20 is ),文件的最小大小为150 is。

代码语言:javascript
复制
file_A1_B1 = open("A1_B1_100000.txt", "r")
file_A2_B2 = open("A2_B2_100000.txt", "r")
file_A1_B2 = open("A1_B2_100000.txt", "r")
file_A2_B1 = open("A2_B1_100000.txt", "r")
file_write = open ("average_generations.txt", "w")
mutation_average = open("mutation_average", "w")

files = [file_A2_B2,file_A2_B2,file_A1_B2,file_A2_B1]

for u in files:
    line = u.readlines()
    list_of_lines = []
    for i in line:
        values = i.split('\t')
        list_of_lines.append(values)

    count = 0
    for j in list_of_lines:
        count +=1

    for k in range(0,count):
        list_of_lines[k].remove('\n')

    length = len(list_of_lines[0])
    print_counter = 4

    for o in range(0,length):
        total = 0
        for p in range(0,count):
            number = float(list_of_lines[p][o])
            total = total + number
        average = total/count
        print average
        if print_counter == 4:
            file_write.write(str(average)+'\n')
            print_counter = 0
        print_counter +=1
file_write.write('\n')
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-27 00:51:55

(这是我的第三个答案,因为我误解了您的代码在我原来的代码中所做的事情,然后在我的第二个错误中犯了一个很小但却很关键的错误--希望三个是一个魅力。

编辑__:由于这似乎是一个流行的答案,多年来我做了一些改进来改进它的实现--大多数不是太重要。因此,如果人们使用它作为模板,它将提供更好的基础。

正如其他人所指出的,您的MemoryError问题很可能是因为您试图将大型文件的全部内容读入内存,然后通过从每一行创建字符串值列表,有效地将所需的内存数量翻一番。

Python的内存限制取决于您的计算机和操作系统有多少物理内存和虚拟内存磁盘空间。即使你没有全部使用它,你的程序“工作”,使用它可能是不切实际的,因为它需要太长时间。

无论如何,避免这种情况的最明显的方法是一次只处理一个文件,这意味着您必须递增地进行处理。

为此,保留每个字段的运行总计列表。完成后,可以通过将相应的总价值除以读取的总行数来计算每个字段的平均值。一旦完成,就可以打印出这些平均值,并将其中一些写入输出文件中。我也有意识地努力使用非常具有描述性的变量名,试图使它可以理解。

代码语言:javascript
复制
try:
    from itertools import izip_longest
except ImportError:    # Python 3
    from itertools import zip_longest as izip_longest

GROUP_SIZE = 4
input_file_names = ["A1_B1_100000.txt", "A2_B2_100000.txt", "A1_B2_100000.txt",
                    "A2_B1_100000.txt"]
file_write = open("average_generations.txt", 'w')
mutation_average = open("mutation_average", 'w')  # left in, but nothing written

for file_name in input_file_names:
    with open(file_name, 'r') as input_file:
        print('processing file: {}'.format(file_name))

        totals = []
        for count, fields in enumerate((line.split('\t') for line in input_file), 1):
            totals = [sum(values) for values in
                        izip_longest(totals, map(float, fields), fillvalue=0)]
        averages = [total/count for total in totals]

        for print_counter, average in enumerate(averages):
            print('  {:9.4f}'.format(average))
            if print_counter % GROUP_SIZE == 0:
                file_write.write(str(average)+'\n')

file_write.write('\n')
file_write.close()
mutation_average.close()
票数 34
EN

Stack Overflow用户

发布于 2010-11-26 12:26:02

您正在将整个文件读入内存(line = u.readlines()),当然,如果文件太大(而且有些文件高达20 GB),这将失败,所以这就是您的问题所在。

更好地迭代每一行:

代码语言:javascript
复制
for current_line in u:
    do_something_with(current_line)

是推荐的方法。

在脚本的后面,您将做一些非常奇怪的事情,比如首先计算列表中的所有项,然后在计数范围内构造一个for循环。为什么不直接迭代列表呢?你剧本的目的是什么?我的印象是,这样做会容易得多。

这是像Python这样的高级语言的优点之一(与C语言相反,在C语言中,您必须自己完成这些内务管理任务):允许Python为您处理迭代,并且只在任何给定的时间在内存中收集实际需要在内存中的内容。

此外,由于您似乎正在处理TSV文件(表-分隔值),您应该看看csv module,它将为您处理\n的所有拆分、删除等。

票数 20
EN

Stack Overflow用户

发布于 2010-11-26 12:30:21

Python可以使用其环境可用的所有内存。我的简单“内存测试”在使用了ActiveState Python2.6之后崩溃了

代码语言:javascript
复制
1959167 [MiB]

在jython 2.5上,它早些时候崩溃了:

代码语言:javascript
复制
 239000 [MiB]

也许我可以配置Jython来使用更多的内存(它使用来自JVM的限制)

测试应用程序:

代码语言:javascript
复制
import sys

sl = []
i = 0
# some magic 1024 - overhead of string object
fill_size = 1024
if sys.version.startswith('2.7'):
    fill_size = 1003
if sys.version.startswith('3'):
    fill_size = 497
print(fill_size)
MiB = 0
while True:
    s = str(i).zfill(fill_size)
    sl.append(s)
    if i == 0:
        try:
            sys.stderr.write('size of one string %d\n' % (sys.getsizeof(s)))
        except AttributeError:
            pass
    i += 1
    if i % 1024 == 0:
        MiB += 1
        if MiB % 25 == 0:
            sys.stderr.write('%d [MiB]\n' % (MiB))

在你的应用程序中,你可以同时读取整个文件。对于这么大的文件,你应该逐行阅读。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4285185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档