This might be a common problem, but I failed to find any good / up-to-date solutions online. I am currently working on a huge dataframe for n companies, whereby we do some heavy calculations per company an then aggregate all the results as a new dataframe. Pretty straightforward, we run df.groupby('company').apply(function) and go grab a cup of coffee while it runs, since this is a single threaded operations.
Now things are getting out of control, with (3h+ wait time), and we're experimenting with multiprocessing. We have implemented the small 'concept' below, whereby we pass a DataFrame.GroupBy to the executor.map callback function and wait for the results.
Problem is, it seems to take a veeeeeeery long time to run, with no feedback on what is actually happening inside each thread. Not sure this is the correct implementation, all I can see is CPU and memory running at 100% use, but the executor never finishes.
Below is a simplified version of the calculations to be done for every company in the database. Advise on how to properly use groupby with multiprocessing is much appreciated.
import time
import concurrent
def append_new_company_technicals(group):
'''
Takes a dataframe and build new columns with technical information
'''
print(group['ticker'].unique())
group.sort_values(by='date', inplace=True)
group['halfvol_30_abs'] = group['px'].rolling(30,min_periods = 21).apply(func)
group['halfvol_180_abs'] = group['px1'].rolling(180,min_periods = 135).apply(func)
group['halfvol_30_rel'] = group['px2'].rolling(30,min_periods = 21).apply(func)
group['halfvol_180_rel'] = group['px3'].rolling(180,min_periods = 135).apply(func)
return group
start = time.time()
with concurrent.futures.ProcessPoolExecutor() as executor:
futures = {executor.map(append_new_company_technicals, df_merged.groupby('ticker'))}
end = time.time()
print("MultiProcessing computation: {} secs ".format(end - start))