Списки / словари Python против множества массивов: производительность против управления памятью

Мне нужно итеративно читать файлы данных и сохранять данные в (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 с
Использование памяти (вверху): 13862 gime_se 20 0 1042 м 934 м 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 с
Использование памяти (вверху): 14850 gime_se 20 0 650 м 542 м 4144 S 0 3,4 22: 31,21 python

Вопрос (ы):

  • Есть ли способ добиться производительности варианта 1 , но держать память под контролем, как в случае 2 ?

  • Кажется, что в случае 1 объем памяти увеличивается при объединении элементов списка (np.concatenate (value, axis = 0)). Как лучше это сделать?

8
задан chan gimeno 8 February 2011 в 17:27
поделиться