2016-07-05 6 views
1

私のコードは(numbaとマルチプロセッシングで)改善しようとしていますが、私の関数には多くの引数があるので、それを得ることはできません。私はすでに他の機能(下記参照)でそれを単純化している多くの入力を伴うforループでの実装

...各エージェント(クラスのインスタンス)として

は、これらのアクションのために互いに独立して、私はPoolforを交換したいと思います。

だから私は、私が電話して渡す薬

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は反復可能な引数を1つしかサポートしないため、すべてを1か所でグループ化する必要があります。 「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'が正しく変更されています。それで、私が反復する新しい 'リスト(エージェント)'を作りました。この場合はうまくいくのでしょうか? –

+0

エージェントのコピーに '' map''を少なくとも適用してください: '' list(agents) ''。なぜリストは変わるのですか? –

+0

しました。 '_pickle.PicklingError:をpickleできません:人口統計の属性検索に失敗しました'というメッセージが表示されます。あなたの例では、私は 'forループ'を開始するまでエージェントを持っていません。 –

関連する問題