【发布时间】:2011-06-23 13:57:37
【问题描述】:
我必须迭代地读取数据文件并将数据存储到 (numpy) 数组中。我选择将数据存储到“数据字段”字典中:{'field1': array1,'field2': array2,...}。
案例 1(列表):
使用lists(或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 蟒蛇
案例 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 蟒蛇
问题:
-
有没有什么方法可以让Case 1的性能,同时又像Case 2一样控制内存?
-
似乎在情况 1 中,连接列表成员 (
np.concatenate(value,axis=0)) 时内存会增长。有更好的想法吗?
【问题讨论】:
-
Numpy 的连接会在您每次使用时创建一个全新的 Numpy 数组。 Numpy 数组的重点是预先分配内存。如果你不这样做,那么你就没有非常明智地使用 Numpy。这就是 Numpy 示例运行缓慢的原因。
-
@Justin:我无法预先分配 numpy 数组,因为我不知道它们之前的长度。这就是为什么我更喜欢使用lists。当我将列表转换为 numpy 数组时出现问题:内存使用量不可挽回地增长。
标签: python performance memory-management