2016-11-25 5 views
0

私は数百万行のpandas Dataframeを持っており、行単位の操作を行う必要があります。私はMulticore CPUを持っているので、マルチプロセッシングを使ってそのプロセスをスピードアップしたいと思います。私がこれをやりたいのは、同じサイズのデータ​​フレームでデータフレームを分割し、それぞれを別々のプロセスで処理することです。これまでのところとても良い... 問題は、私のコードがOOPスタイルで書かれていて、マルチプロセッサプールを使ってPickleエラーが出るということです。私がしていることは、クラス関数self.Xへの参照をプールに渡すことです。私はさらに、X(読み取りアクセスのみ)のクラス属性を使用します。私は実際に関数型プログラミングに戻ってほしくない...したがって、OOP環境でマルチプロセッシングを行うことは可能でしょうか?クラス関数とクラス属性を使用したマルチプロセッシング

答えて

0

クラス内のすべての要素(サブプロセスに渡す)がpicklableである限り、可能である必要があります。それがあなたが確認しなければならない唯一のことです。あなたのクラスに、そうでない要素があれば、それをプールに渡すことはできません。 self.xだけを渡しても、self.yのようなものはすべてpicklableでなければなりません。

私はそのように私のパンダのデータフレームの処理を実行します。私が持っていない

import pandas as pd 
import multiprocessing as mp 
import numpy as np 
import time 


def worker(in_queue, out_queue): 
    for row in iter(in_queue.get, 'STOP'): 
     value = (row[1] * row[2]/row[3]) + row[4] 
     time.sleep(0.1) 
     out_queue.put((row[0], value)) 

if __name__ == "__main__": 
    # fill a DataFrame 
    df = pd.DataFrame(np.random.randn(1e5, 4), columns=list('ABCD')) 

    in_queue = mp.Queue() 
    out_queue = mp.Queue() 

    # setup workers 
    numProc = 2 
    process = [mp.Process(target=worker, 
          args=(in_queue, out_queue)) for x in range(numProc)] 

    # run processes 
    for p in process: 
     p.start() 

    # iterator over rows 
    it = df.itertuples() 

    # fill queue and get data 
    # code fills the queue until a new element is available in the output 
    # fill blocks if no slot is available in the in_queue 
    for i in range(len(df)): 
     while out_queue.empty(): 
      # fill the queue 
      try: 
       row = next(it) 
       in_queue.put((row[0], row[1], row[2], row[3], row[4]), block=True) # row = (index, A, B, C, D) tuple 
      except StopIteration: 
       break 
     row_data = out_queue.get() 
     df.loc[row_data[0], "Result"] = row_data[1] 

    # signals for processes stop 
    for p in process: 
     in_queue.put('STOP') 

    # wait for processes to finish 
    for p in process: 
     p.join() 

この方法では、データフレームの大きな塊を渡すために、私は私のクラスではpickle化可能な要素を考える必要はありません。

関連する問題