gpt4 book ai didi

Python 列表/字典与 numpy 数组 : performance vs. 内存控制

转载 作者:太空狗 更新时间:2023-10-29 21:10:24 25 4
gpt4 key购买 nike

我必须反复读取数据文件并将数据存储到 (numpy) 数组中。我选择将数据存储到“数据字段”字典中:{'field1': array1,'field2': array2,...}

案例 1(列表):

使用列表(或collections.deque())“附加”新数据数组,代码高效。但是,当我连接存储在列表中的数组时,内存增长 并且我没有设法再次释放它。示例:

filename = 'test'
# data file with a matrix of shape (98, 56)
nFields = 56
# Initialize data dictionary and list of fields
dataDict = {}

# data directory: each entry contains a list
field_names = []
for i in xrange(nFields):
field_names.append(repr(i))
dataDict[repr(i)] = []

# Read a data file N times (it represents N files reading)
# file contains 56 fields of arbitrary length in the example
# Append each time the data fields to the lists (in the data dictionary)
N = 10000
for j in xrange(N):
xy = np.loadtxt(filename)
for i,field in enumerate(field_names):
dataDict[field].append(xy[:,i])

# concatenate list members (arrays) to a numpy array
for key,value in dataDict.iteritems():
dataDict[key] = np.concatenate(value,axis=0)

计算时间:63.4 s
内存使用情况(顶部):13862 gime_se 20 0 1042m 934m 4148 S 0 5.8 1:00.44 python

案例 2(numpy 数组):

每次读取时直接连接 numpy 数组效率低下内存仍然受控 .示例:

nFields = 56
dataDict = {}
# data directory: each entry contains a list
field_names = []
for i in xrange(nFields):
field_names.append(repr(i))
dataDict[repr(i)] = np.array([])

# Read a data file N times (it represents N files reading)
# Concatenate data fields to numpy arrays (in the data dictionary)
N = 10000
for j in xrange(N):
xy = np.loadtxt(filename)
for i,field in enumerate(field_names):
dataDict[field] = np.concatenate((dataDict[field],xy[:,i]))

计算时间:1377.8 s
内存使用情况(顶部):14850 gime_se 20 0 650m 542m 4144 S 0 3.4 22:31.21 python

问题:

  • 有没有什么方法既能达到情况 1 的性能,又能像情况 2 那样控制内存?

  • 似乎在情况 1 中,连接列表成员 (np.concatenate(value,axis=0)) 时内存会增加。更好的想法?

最佳答案

根据我的观察,这是正在发生的事情。没有真正的内存泄漏。相反,Python 的内存管理代码(可能与您所在的任何操作系统的内存管理有关)决定在程序中保留原始字典(没有串联数组的字典)使用的空间。但是,它可以免费重复使用。我通过执行以下操作证明了这一点:

  1. 将您作为答案提供的代码制作成返回 dataDict 的函数。
  2. 调用该函数两次并将结果分配给两个不同的变量。

执行此操作时,我发现使用的内存量仅从 ~900 GB 增加到 ~1.3 GB。如果没有额外的字典内存,根据我的计算,Numpy 数据本身应该占用大约 427 MB,所以加起来。我们的函数创建的第二个初始的、未连接的字典只使用了已经分配的内存。

如果你真的不能使用超过 ~600 MB 的内存,那么我建议你使用 Numpy 数组,就像在内部使用 Python 列表所做的那样:分配一个包含一定数量列的数组,当你已经用完了,创建一个包含更多列的扩大数组并将数据复制过来。这将减少连接的数量,这意味着它会更快(尽管仍然不如列表快),同时减少内存使用。当然,实现起来也比较痛苦。

关于Python 列表/字典与 numpy 数组 : performance vs. 内存控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4935892/

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