gpt4 book ai didi

python - 将文本文件读入列表,然后存储在字典中会填满系统内存? (我做错了什么?)Python

转载 作者:太空宇宙 更新时间:2023-11-04 09:21:16 26 4
gpt4 key购买 nike

我有 43 个文本文件,“43 个项目占用磁盘 232.2 MB(232,129,355 字节)”。将它们读入内存的内容(参见下面的代码)。我遇到的问题是磁盘上每个大约 5.3mb 的文件导致 python 使用额外的 100mb 系统内存。如果检查 dict() getsizeof() 的大小(请参阅输出示例)。当 python 高达 3GB 的系统内存时,getsizeof(dict()) 仅使用 6424 字节的内存。我不明白什么在使用内存。

什么占用了所有内存?

相关链接的不同之处在于 python 报告的内存使用是“正确的” related question我对其他解决方案 DB 不是很感兴趣....我更感兴趣的是了解正在发生的事情,所以我知道将来如何避免它。也就是说,如果有帮助,使用其他 python 内置数组而不是列表是很好的建议。我听说过使用孔雀鱼来查找正在使用内存的建议。

示例输出:

Loading into memory: ME49_800.txt
ME49_800.txt has 228484 rows of data
ME49_800.txt has 0 rows of masked data
ME49_800.txt has 198 rows of outliers
ME49_800.txt has 0 modified rows of data
280bytes of memory used for ME49_800.txt
43 files of 43 using 12568 bytes of memory
120

示例数据:

CellHeader=X    Y   MEAN    STDV    NPIXELS
0 0 120.0 28.3 25
1 0 6924.0 1061.7 25
2 0 105.0 17.4 25

代码:

import csv, os, glob
import sys


def read_data_file(filename):
reader = csv.reader(open(filename, "U"),delimiter='\t')
fname = os.path.split(filename)[1]
data = []
mask = []
outliers = []
modified = []

maskcount = 0
outliercount = 0
modifiedcount = 0

for row in reader:
if '[MASKS]' in row:
maskcount = 1
if '[OUTLIERS]' in row:
outliercount = 1
if '[MODIFIED]' in row:
modifiedcount = 1
if row:
if not any((maskcount, outliercount, modifiedcount)):
data.append(row)
elif not any((not maskcount, outliercount, modifiedcount)):
mask.append(row)
elif not any((not maskcount, not outliercount, modifiedcount)):
outliers.append(row)
elif not any((not maskcount, not outliercount, not modifiedcount)):
modified.append(row)
else: print '***something went wrong***'

data = data[1:]
mask = mask[3:]
outliers = outliers[3:]
modified = modified[3:]
filedata = dict(zip((fname + '_data', fname + '_mask', fname + '_outliers', fname+'_modified'), (data, mask, outliers, modified)))
return filedata


def ImportDataFrom(folder):

alldata = dict{}
infolder = glob.glob( os.path.join(folder, '*.txt') )
numfiles = len(infolder)
print 'Importing files from: ', folder
print 'Importing ' + str(numfiles) + ' files from: ', folder

for infile in infolder:
fname = os.path.split(infile)[1]
print "Loading into memory: " + fname

filedata = read_data_file(infile)
alldata.update(filedata)

print fname + ' has ' + str(len(filedata[fname + '_data'])) + ' rows of data'
print fname + ' has ' + str(len(filedata[fname + '_mask'])) + ' rows of masked data'
print fname + ' has ' + str(len(filedata[fname + '_outliers'])) + ' rows of outliers'
print fname + ' has ' + str(len(filedata[fname +'_modified'])) + ' modified rows of data'
print str(sys.getsizeof(filedata)) +'bytes'' of memory used for '+ fname
print str(len(alldata)/4) + ' files of ' + str(numfiles) + ' using ' + str(sys.getsizeof(alldata)) + ' bytes of memory'
#print alldata.keys()
print str(sys.getsizeof(ImportDataFrom))
print ' '

return alldata


ImportDataFrom("/Users/vmd/Dropbox/dna/data/rawdata")

最佳答案

字典本身非常小——大部分数据是存储在列表中的文件的全部内容,每行包含一个元组。 20 倍的尺寸增加比我预期的要大,但似乎是真实的。将示例输入中的 27 字节行拆分为元组,得到 309 字节(在 64 位计算机上递归计数)。再加上一些未知的内存分配开销,20 倍并非不可能。

备选方案:为了更紧凑的表示,您希望将字符串转换为整数/ float 并将它们紧密打包(没有所有指针和单独的对象)。我说的不只是一行(尽管这是一个开始),而是一整行的列表 - 因此每个文件将仅由四个二维数字数组表示。 array 模块只是一个开始,但您真正需要的是 numpy 数组:

# Using explicit field types for compactness and access by name
# (e.g. data[i]['mean'] == data[i][2]).
fields = [('x', int), ('y', int), ('mean', float),
('stdv', float), ('npixels', int)]
# The simplest way is to build lists as you do now, and convert them
# to numpy array when done.
data = numpy.array(data, dtype=fields)
mask = numpy.array(mask, dtype=fields)
...

这让我每行花费 40 字节(根据 .data 属性测量;sys.getsizeof 报告该数组有 80 字节的恒定开销,但没有'查看实际使用的数据)。这仍然比原始文件多 ~1.5,但应该很容易放入 RAM。

我看到你的两个字段被标记为“x”和“y” - 如果你的数据很密集,你可以按它们排列 - data[x,y]==... - 而不是仅仅存储 (x ,y,...) 记录。除了稍微更紧凑之外,这将是最合理的结构,允许更容易处理。

如果您需要处理比 RAM 容量更多的数据,pytables 是一个很好的库,可以高效访问文件中的紧凑(甚至压缩)表格数据。 (在这方面比一般的 SQL 数据库要好得多。)

关于python - 将文本文件读入列表,然后存储在字典中会填满系统内存? (我做错了什么?)Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2306523/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com