4

pandasの新機能である、私はすでに行単位の適用操作を並列化したいと考えています。これまで私は見つけたParallelize apply after pandas groupbyしかし、それはグループ化されたデータフレームのために働くように思えます。pandasパラレル化適用

私は休暇のリストを持っています。私は現在の行/日付に対して、この日の前後の休日を次の休暇にしたいと考えています。

これは私が経由して呼び出す関数が適用されます。

def get_nearest_holiday(x, pivot): 
    nearestHoliday = min(x, key=lambda x: abs(x- pivot)) 
    difference = abs(nearesHoliday - pivot) 
    return difference/np.timedelta64(1, 'D') 

がどのように私はそれをスピードアップすることができますか?

編集

私はニシキヘビプールで少し実験 - しかし、それはどちらも素敵なコードでした、また私は私の計算結果を手に入れました。

+0

"パイソン・プール" - スレッドやプロセス? –

+0

私はマルチプロセッシングを使用していました.Pool(processes = #ofCPU) –

+0

マルチプロセッシングはコードのスピードアップを保証していませんが、コードが正しく動作していないため、そこで何が実行されているのかを知るのは難しいです。あなたはそれについてあなたの質問をしたいかもしれません(FWIW、このアプローチは私の最善の策です)。 –

答えて

2

私は、物事を並行して試してみるという道のりは、おそらくこれを複雑にしていると思います。私たちは、

import pandas as pd 

dates = pd.to_datetime(['2016-01-03', '2016-09-09', '2016-12-12', '2016-03-03']) 

...

はちょうどいくつかの日付を見てみましょう...う、あなたの走行距離は変更になる場合がありますので、私は大規模なサンプルにこの方法を試していないが、それはあなたのアイデアを与える必要があります

DatetimeIndex(['2016-01-01', '2016-01-18', '2016-02-15', '2016-05-30', 
       '2016-07-04', '2016-09-05', '2016-10-10', '2016-11-11', 
       '2016-11-24', '2016-12-26', 
       ... 
       '2030-01-01', '2030-01-21', '2030-02-18', '2030-05-27', 
       '2030-07-04', '2030-09-02', '2030-10-14', '2030-11-11', 
       '2030-11-28', '2030-12-25'], 
       dtype='datetime64[ns]', length=150, freq=None) 
を: - pandas.tseries.holidayからいくつかの休日のデータを使用し

from pandas.tseries.holiday import USFederalHolidayCalendar 

holiday_calendar = USFederalHolidayCalendar() 
holidays = holiday_calendar.holidays('2016-01-01') 

これは私たちに与える...実際に私たちはDatetimeIndexを望むことに注意してください

今、私たちはsearchsortedを使用して、元の日付の最寄りの最寄りの休日のインデックスを見つける:

next_nearest_diff = pd.to_timedelta(next_nearest.values - dates.values).days 
# array([15, 31, 14, 88]) 

あなたは注意する必要があります

indices = holidays.searchsorted(dates) 
# array([1, 6, 9, 3]) 
next_nearest = holidays[indices] 
# DatetimeIndex(['2016-01-18', '2016-10-10', '2016-12-26', '2016-05-30'], dtype='datetime64[ns]', freq=None) 

は次に、2つの間の差を取りますインデックスはラップアラウンドしないで、以前の日付では、indices - 1で計算しますが、それは(私が望む)比較的良いベースとして機能するはずです。

+0

私はあなたのコードで最低限の例を更新しました(bootomを見てください)。休日のために "私のdateimeIndices"を使用しようとすると、私は範囲外のインデックスを受け取ります。 –

+0

コメントは議論の延長ではありません。この会話は[チャットに移動]されています(http://chat.stackoverflow.com/rooms/122604/discussion-on-answer-by-ninja-puppy-parallelize-pandas-apply)。 –

0

並列的なアプローチでは、これがParallelize apply after pandas groupbyに基づいて回答です:

from joblib import Parallel, delayed 
import multiprocessing 

def get_nearest_dateParallel(df): 
    df['daysBeforeHoliday'] = df.myDates.apply(lambda x: get_nearest_date(holidays.day[holidays.day < x], x)) 
    df['daysAfterHoliday'] = df.myDates.apply(lambda x: get_nearest_date(holidays.day[holidays.day > x], x)) 
    return df 

def applyParallel(dfGrouped, func): 
    retLst = Parallel(n_jobs=multiprocessing.cpu_count())(delayed(func)(group) for name, group in dfGrouped) 
    return pd.concat(retLst) 

print ('parallel version: ') 
# 4 min 30 seconds 
%time result = applyParallel(datesFrame.groupby(datesFrame.index), get_nearest_dateParallel) 

が、それはO(N * number_of_holidays)を必要としないので、私はNinjaPuppyのアプローチ@好む

関連する問題