1

Я хотел бы использовать многопроцессорную обработку для генерации матрицы перехода цепи Маркова.Использование многопроцессорности с несколькими возвращаемыми значениями и упорядоченными словарями

Функция generateKeys() создает словарь с новыми скоростями и словарь с новыми ключами для каждого состояния в пространстве состояний после перехода.

from collections import OrderedDict 

def generateKeys(): 
    idxDict = OrderedDict() 
    rateDict = OrderedDict() 
    for key,state in stateDict.items():    
     newkeys,rates = transitionFunction(state)    
     idxDict[key] = newkeys 
     rateDict[key] = rates 
    return idxDict,rateDict 

Причина использовать OrderedDict здесь является то, что ключи перепутать с обычным dict на следующей стадии (В следующем шаге я конкатенировать Numpy массивы в словарях и хранить их в разреженном coo_matrix).

Поскольку словарные ключи уникальны, должно быть возможно запустить generateKeys() параллельно и заполнить два словаря намного быстрее на многоядерной машине.

Я рассмотрел пакет multiprocessing и некоторые примеры, но примеры, которые я видел, были для одного возвращаемого значения и без заказанных словарей. Я пока не понимаю, как применить его в моих настройках. Может ли кто-нибудь показать мне, как это работает?

+0

Если необходимо сохранить порядок для 'transitionFunction' вызовов, параллелизм не путь .. – Cyrbil

+0

@Cyrbil Хм, ты прав. Я уже вижу обходное решение для этого, используя регулярные словари и сортировку по ключам. – Forzaa

ответ

2

Если transitionFunction может применить состояния в любом порядке:

transitionFunction('A') 
transitionFunction('B') 

# is equivalent to 
transitionFunction('B') 
transitionFunction('A') 

Вы можете использовать:

from multiprocessing import Pool, cpu_count 

p = Pool(cpu_count()) 
results = p.map(transitionFunction, stateDict.values()) 

results будет иметь тот же порядок, чем значения stateDict, то вы можете создать свой Dict с:

idxDict = dict(zip(stateDict.keys(), i[0] for i in results)) 
rateDict = dict(zip(stateDict.keys(), i[1] for i in results)) 

Если transitionFunction может не применить состояния в любом порядке, то вы будете иметь непредсказуемые результаты ...

+0

Спасибо за помощь. Я думаю, что это должно решить мою проблему. Теперь следующая проблема заключается в том, что я не могу назвать это изнутри класса: 'p.map (self.transitionFunction, self.stateDict.values ​​())' возвращает следующую ошибку: 'Невозможно pickle : поиск атрибута __builtin __. instancemethod failed'. – Forzaa

+0

По этой проблеме обратитесь к многим сообщениям, которые уже упоминают об этом: http://stackoverflow.com/search?tab=votes&q=Can%27t%20pickle%20%3Ctype%20%27instancemethod%27%3E – Cyrbil

0

Существует, по-видимому, решение для обмена словарем между независимыми процессами. Посмотрите here для описания. ИМХО это самый простой способ справиться с вашей проблемой. Однако это решение не поддерживает OrderedDict. Поэтому, если вы можете найти способ сделать это без них, это сработает. Может быть, вы можете передать/преобразовать вас после этого в нужную форму.

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