2013-04-20 1 views
4

У меня возникла проблема выполнения инициализации словаря четырехмерного тензора.Словарь 4-D numpy массива: как оптимизировать?

У меня есть список имен коэффициентов:

cnames = ['CN', 'CM', 'CA', 'CY', 'CLN' ...]; 

, не фиксированный размер (это зависит от верхнего кода). Для каждого коэффициента я должен генерировать тензор 4-D [nalpha Х nmach Х nbeta Х NALT] нулей (для целей предраспределения), так что я:

#Number of coefficients 
numofc = len(cnames); 

final_data = {}; 
#I have to generate <numofc> 4D matrixes 
for i in range(numofc): 
    final_data[cnames[i]]=n.zeros((nalpha,nmach,nbeta,nalt)); 

каждый индекс представляет собой целое число от 10 до 30. каждый индекс представляет собой целое число от 100 до 200

Это занимает 4 минуты. Как я могу ускорить это? Или я делаю что-то неправильно?

+1

Более питоновское решение (бит быстрее) было бы следующим: 'final_data = {cname: np.zeros ((nalpha, nmach, nbeta, nalt)) для cname в cnames}' – root

ответ

5

Код, который вы отправили, не должен занимать 4 минуты (за исключением случаев, когда cnames является чрезвычайно большим или у вас очень мало ОЗУ и он вынужден использовать пространство подкачки).

import numpy as np 

cnames = ['CN', 'CM', 'CA', 'CY', 'CLN']*1000 
nalpha,nmach,nbeta,nalt = 10,20,30,40 
#Number of coefficients 
numofc = len(cnames) 

final_data = {} 
#I have to generate <numofc> 4D matrixes 
for i in range(numofc): 
    final_data[cnames[i]]=np.zeros((nalpha,nmach,nbeta,nalt)) 

Даже если cnames имеет 5000 элементов, то все равно должны принимать только порядка пары секунд:

% time test.py 
real 0m4.559s 
user 0m0.856s 
sys 0m3.328s 

с запятой в конце заявления предполагает, у вас есть опыт в каком-то другом языке. Будьте осторожны с переводом команд из этого языка по строкам в NumPy/Python. Кодирование в NumPy, как и в C, является рецептом медленности.

В частности, старайтесь избегать обновления элементов в элементе-элементе массива. Это отлично работает на C, но с Python работает очень медленно. NumPy достигает скорости, делегируя функции, закодированные в Fortran или Cython или C или C++. При обновлении массивов по элементам вы используете петли Python, которые не так быстро.

Вместо этого попробуйте перефразировать вычисления в терминах операций на всех массивах (или, по крайней мере, срезах массивов).

Я, вероятно, слишком много размышлял о причине проблемы. Вам нужно profile your code, а затем, если вы хотите получить более конкретную помощь, опубликуйте результат профиля плюс проблемный код (наиболее полезно в виде SSCCE).

+0

Спасибо за ваш ответ. Я проверил, и я ошибся в размерах тензора. Каждый индекс составляет от 100 до 180. 4 минуты могут быть в порядке в этом случае? – SolidSnake

+3

@ TiD91 - Если у вас достаточно барана, это займет всего несколько секунд. Что, вероятно, происходит, так это то, что у вас заканчивается баран и начинает использовать пространство подкачки. 100x100x100x100 массив int64 будет занимать ~ 760 МБ, в то время как массив размером 200x200x200x200 будет занимать ~ 12 ГБ. Если память в основном заполнена, но у вас достаточно памяти для хранения одного массива, вы не получите «MemoryError». Вместо этого ваша ОС будет менять содержимое вашей RAM на диск, чтобы освободить место для нового массива. Чтение и запись нескольких ГБ на диск происходит медленно. –

Смежные вопросы