2016-07-05 7 views
1

내 함수가 많은 인수를 가지고 있기 때문에 numba 및 다중 처리와 함께 코드를 향상 시키려고했지만 꽤 얻을 수 없습니다. 이미 다른 기능 (아래 참조)를 단순화많은 입력이있는 for 루프에서 풀 구현

... 각 에이전트 (클래스 인스턴스)로

이러한 작업을 위해 서로 독립적이다, 나는 Poolfor를 교체하고 싶습니다.

그래서 나는 많은 기능 I 에이전트

나는 풀링 기능이 필요로하는 모든 인수를 추가 할
from multiprocessing import Pool 

p = Pool(4) 
p.map(pooling, list(agents)) 

하지만, 목록 전화를 통과 할 pooling()을 얻을 것?

그것은이므로 :

def check_demographics(month, my_agents, families, firms, year, mortality_men, mortality_women, fertility, state_id): 

    dummy = list(my_agents) 
    d = str(state_id.iloc[0]) 

# Place where I would like to replace the LOOP. All below would be a function 

    for agent in dummy: 

     if agent.get_region_id()[:2] == d: 

      # Brithday 
      if month % 12 == agent.month - 1: 
       agent.update_age() 

      # Mortality probability 
      if agent.get_gender() == 'Male': 
       prob = mortality_men[mortality_men['age'] == agent.get_age()][year].iloc[0] 

      # When gender is Female 
      else: 
       # Extract specific agent data to calculate mortality 'Female' 
       prob = mortality_women[mortality_women['age'] == agent.get_age()][year].iloc[0] 

      # Give birth decision 
       age = agent.get_age() 
       if 14 < age < 50: 
        pregnant(agent, fertility, year, families, my_agents) 

      # Mortality procedures 
      if fixed_seed.random() < prob: 
       mortal(my_agents, my_graveyard, families, agent, firms) 

그것은 내 프로그램에 기능을 소모 대부분의 시간입니다. @jit은별로 도움이되지 않습니다.

감사합니다.

+1

참고 : 전역 변수 또는 매개 변수 "my_graveyard"가 없습니다. –

+0

정말로 감사합니다. –

답변

1

예, 많은 매개 변수가 있습니다. 클래스 사용을 고려하십시오.

자, Pool.map은 하나의 반복 가능한 인수 만 지원하므로 모든 것을 한 곳에서 그룹화해야합니다. "Facade"패턴을 사용하는 것이 좋습니다 : 매개 변수없이 모든 필수 매개 변수를 저장하고 단일 메서드 (저는 check이라고 함)를 사용하는 중간 클래스입니다 (메서드).

class Facade(object): 
    def __init__(self, agent, d, families, fertility, firms, month, mortality_men, mortality_women, my_agents, 
       my_graveyard, year): 
     self.agent = agent 
     self.d = d 
     self.families = families 
     self.fertility = fertility 
     self.firms = firms 
     self.month = month 
     self.mortality_men = mortality_men 
     self.mortality_women = mortality_women 
     self.my_agents = my_agents 
     self.my_graveyard = my_graveyard 
     self.year = year 

    def check(self): 
     (agent, d, families, fertility, firms, 
     month, mortality_men, mortality_women, 
     my_agents, my_graveyard, year) = (
      self.agent, self.d, self.families, self.fertility, self.firms, 
      self.month, self.mortality_men, self.mortality_women, 
      self.my_agents, self.my_graveyard, self.year) 
     if agent.get_region_id()[:2] == d: 

      # Brithday 
      if month % 12 == agent.month - 1: 
       agent.update_age() 

      # Mortality probability 
      if agent.get_gender() == 'Male': 
       prob = mortality_men[mortality_men['age'] == agent.get_age()][year].iloc[0] 

      # When gender is Female 
      else: 
       # Extract specific agent data to calculate mortality 'Female' 
       prob = mortality_women[mortality_women['age'] == agent.get_age()][year].iloc[0] 

       # Give birth decision 
       age = agent.get_age() 
       if 14 < age < 50: 
        pregnant(agent, fertility, year, families, my_agents) 

      # Mortality procedures 
      if fixed_seed.random() < prob: 
       mortal(my_agents, my_graveyard, families, agent, firms) 

비고 : 내 리팩토링 정말 추한,하지만 선명도에 대한 변경 변수 이름을 유지하고 싶었다. 당신은 각 에이전트는 루프를 분석 한 후, 난 당신이 에이전트의 전체 목록을 (필요 볼 서로 만의 독립적이라고 말했다

def check_demographics(month, my_agents, families, firms, 
         year, mortality_men, mortality_women, 
         fertility, state_id, my_graveyard): 
    d = str(state_id.iloc[0]) 
    pool = Pool(4) 
    facades = [Facade(agent, d, families, fertility, firms, 
         month, mortality_men, mortality_women, 
         my_agents, my_graveyard, year) 
       for agent in my_agents] 
    pool.map(Facade.check, facades) 

:

는 그런 다음 루프는 그런 일이 될 수 있습니다 my_agents 매개 변수). Facade 클래스에서는 분명합니다. 따라서 에이전트 목록이 변경되어서는 안되며 각 에이전트의 내부 상태는 루핑 중에 고정되어야합니다.

+0

훌륭합니다. 감사합니다. 그러나 당신은 my_agents리스트가 바뀌었다. 그래서 반복하는 새로운'list (agents) '를 만들었습니다. 이 경우 작동합니까? –

+0

최소한 에이전트 사본에''map''을 적용하십시오 :''list (agents)''. 목록이 변경되는 이유는 무엇입니까? –

+0

나는 그랬다. 또한 _pickle.PicklingError : 을 pickle 할 수 없습니다. 인구 통계에 대한 속성 조회 확인에 실패했습니다. '라는 메시지가 나타납니다. 목록에있는 사람이 죽을 때 에이전트를 제거해야하므로 목록이 변경됩니다. 그리고 예제에서, 나는 for 루프를 시작하기 전까지 에이전트를 가지고 있지 않습니다. –