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

将文本文件读入列表,然后存储在字典中,是否会填充系统内存?(A我做错了什么?)Python,python,memory,file,Python,Memory,File,我有43个文本文件,消耗“磁盘上232.2MB(232129355字节)用于43个项目”。如何将它们读入内存(请参阅下面的代码)。我遇到的问题是,磁盘上大约5.3mb的每个文件都会导致python额外使用100mb的系统内存。如果需要,请检查dict()getsizeof()的大小(请参阅输出示例)。当python的系统内存达到3GB时,getsizeof(dict())只使用6424字节的内存。我不明白是什么在使用内存 是什么耗尽了所有的内存 相关链接的不同之处在于,python报告的内存使用

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

是什么耗尽了所有的内存

相关链接的不同之处在于,python报告的内存使用是“正确的” 我对其他解决方案不太感兴趣。。。。我对了解正在发生的事情更感兴趣,因此我知道如何在将来避免它。也就是说,如果有帮助的话,最好使用其他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")
样本数据:

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")
代码:

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")

此行专门获取函数对象的大小:

print str(sys.getsizeof(ImportDataFrom))
那不太可能是你感兴趣的

容器的大小不包括它包含的数据的大小。例如,考虑:

>>> import sys
>>> d={}
>>> sys.getsizeof(d)
140
>>> d['foo'] = 'x'*99
>>> sys.getsizeof(d)
140
>>> d['foo'] = 'x'*9999
>>> sys.getsizeof(d)
140

如果您想要容器的大小加上所有包含内容的大小,那么您必须编写自己的(可能是递归的)函数,该函数到达容器内部并对每个字节进行挖掘。或者,您可以使用第三方库,如或。

此行专门获取函数对象的大小:

print str(sys.getsizeof(ImportDataFrom))
那不太可能是你感兴趣的

容器的大小不包括它包含的数据的大小。例如,考虑:

>>> import sys
>>> d={}
>>> sys.getsizeof(d)
140
>>> d['foo'] = 'x'*99
>>> sys.getsizeof(d)
140
>>> d['foo'] = 'x'*9999
>>> sys.getsizeof(d)
140

如果您想要容器的大小加上所有包含内容的大小,那么您必须编写自己的(可能是递归的)函数,该函数到达容器内部并对每个字节进行挖掘。或者,您可以使用第三方库,如或。

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

备选方案:对于更紧凑的表示,您希望将字符串转换为整数/浮点数,并将其紧密打包(无需所有指针和单独的对象)。我说的不仅仅是一行(虽然这是一个开始),而是一个完整的行列表——因此每个文件将仅由四个二维数字数组表示。
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”-如果你的数据很密集,你可以用它们来排列-数据[x,y]==…-而不仅仅是存储(x,y,…)记录。除了稍微紧凑之外,它将是最合理的结构,允许更容易的处理


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

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

备选方案:对于更紧凑的表示,您希望将字符串转换为整数/浮点数,并将其紧密打包(无需所有指针和单独的对象)。我说的不仅仅是一行(虽然这是一个开始),而是一个完整的行列表——因此每个文件将仅由四个二维数字数组表示。
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”-如果你的数据很密集,你可以用它们来排列-数据[x,y]==…-而不仅仅是存储(x,y,…)记录。除了稍微紧凑之外,它将是最合理的结构,允许更容易的处理


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

好吧,我想我需要看看Pypler或guppy。你会认为我所做的是个问题吗。有更好的办法吗?我想我可以做更多的研究。还要注意的是,getsizeof(filedata)每次都大致相同,只有alldata随着每个文件不断增长。@Vincent,我看不出有什么不对劲的地方(除了测量空间的尝试)——DICT只是内存昂贵。您可以考虑移动<代码> ALATDATIO/COD