Применить в pandas возвращает список столбцов df, а не вычисленные значения при многопоточности - PullRequest
0 голосов
/ 07 ноября 2018

Мне предоставляют pandas dataframe urls_df, содержащую части, которые объединяются, образуя URL. Есть два основных способа комбинирования этих компонентов и получения содержимого URL. URLObject заботится об этой части и возвращает как веб-контент, так и контент сервера из созданного URL, в формате dict. Вот как это работает:

list(df.apply(lambda row: getattr(URLObject(row[discriminant_col],                                                             
                                            row['col_1'],
                                            row['col_2']), 
                                   attribute), 
               axis=1)) #returns list of dicts

urls_df содержит 2 дискриминантных столбца, ['URL_DISCRIMINANT_COLUMN_1','URL_DISCRIMINANT_COLUMN_2'], которые немного меняют URL для получения определенных папок. Теперь для каждой строки мне нужно запустить getattr(URLObject... сверху, 4 раза для каждого источника, 2 папки из Интернета и 2 с сервера. Задача состоит в том, чтобы запустить их параллельно, как показано ниже. Я делаю 4 threads, по одному на столбец. У меня проблема в том, что из-за многопоточности данные иногда выходят нормально, а иногда вместо содержимого возвращаются имена столбца urls_df. Может кто-нибудь объяснить, что я делаю неправильно и что я могу сделать, чтобы исправить эту проблему?

from multiprocessing.dummy import Pool as ThreadPool

    def do_threaded(tasks):
        with ThreadPool(len(tasks)) as pool:
            results = [pool.apply_async(*t) for t in tasks]
            results = [res.get() for res in results] 
        return results


    def func(df, discriminant_col, arribute):             
        return list(df.apply(lambda row: getattr(URLObject(row[discriminant_col],                                                             
                                                          row['col_1'],
                                                          row['col_2']), 
                                                  attribute), 
                                  axis=1))

urls_df = pd.DataFrame()# this is a pandas dataframe with data     
tasks = [(func, (input_df, discriminant, atr)) for atr in [server_data, web_data]  for discriminant in ['URL_DISCRIMINANT_COLUMN_1','URL_DISCRIMINANT_COLUMN_2']] 

table = do_threaded(tasks)
headers = [header.pop(0) for header in table]
content_df = pd.DataFrame(table).
content_df.columns = headers
...