【问题标题】:Python - store results from multiprocessing in a global dataframePython - 将多处理的结果存储在全局数据框中
【发布时间】:2021-09-11 03:20:34
【问题描述】:

我有一个包含 32 个变量和约 900 个观察值的数据集,我想在多元线性回归模型 (statsmodel ols) 中进行测试。我想看看哪些最适合一起工作-我基本上是蛮力强迫的,因为任何人都不清楚这种关系。不幸的是,它需要几个小时才能完成。 我决定尝试多处理以加快速度。对于每个变量组合,脚本将:

  • 建立声明
  • 执行线性回归
  • 提取汇总值(p / Bic / Rsquared)
  • 将它们存储在数据框中

我有前 3 个工作,但是当我尝试将其存储在数据帧中并在最后输出时,它什么也不返回。有任何想法吗?我已将数据框声明为全局。 我确信该功能可以正常工作,因为我在原始模型中使用了它的修改版本。

import pandas as pd
import random
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
from statistics import mean
from statistics import median
from multiprocessing import Pool
import datetime
import os

#Create the dataframe
inLoc='C:\\temp\\retailer_cost\\'
inName='raw_data_v1_2.csv'
inFile = inLoc + inName
df=pd.read_csv(inFile)

#Create the dataframe to store the summary results in 
summaryDF = pd.DataFrame(columns=['modelID','statement','num_vars','BIC','AIC','RSQ','RSQ_ADJ','CONDITION','AVG_PVALUE','MEDIAN_PVALUE','POSITIVE_VALUES'])

combList = [['a','b','c','d','e'],
            ['a','b','c','d',],
            ['a','b','c','e'],
            ['a','b','d','e'],
            ['a','c','d','e'],
            ['b','c','d','e']]

################################################################
#Function
################################################################

def processor(combin):
    date_time = str(datetime.datetime.now().time())
    #Declare SummaryDF as global 
    global summaryDF
    stmt,interceptOut = createStmt('adjusted_value', combin)
    print(stmt)
    mod = smf.ols(formula=stmt, data=df)
    results = mod.fit()
    modID = str(date_time) + '_' + str(interceptOut)
    avg = mean(list(results.pvalues))
    mdn = median(list(results.pvalues))
    #Extract coefficients
    pVals = list(dict(results.pvalues).items())
    coeffs = list(dict(results.params).items())
    tVals = list(dict(results.tvalues).items())
    #Create the record to add
    summOut = {'modelID': modID,  'statement': stmt, 'num_vars': str(len(combin)), 'BIC': str(results.bic) ,'AIC': str(results.aic) ,'RSQ': str(results.rsquared) ,'RSQ_ADJ': str(results.rsquared_adj),'CONDITION': str(results.condition_number),'AVG_PVALUE': str(avg),'MEDIAN_PVALUE': str(mdn)}
summaryDF = summaryDF.append(summOut, ignore_index = True)

if __name__ == '__main__':
    pool = Pool()                         
    pool.map(processor, combList)

#Produces nothing
summaryDF.to_csv('c:\\temp\\olsModelOut.csv', index=False)

【问题讨论】:

  • 多处理在它们自己的进程中运行你的函数;进程之间不共享内存空间;您的每个进程都在更新自己的全局变量版本。您必须明确地将每个进程的结果返回/发送到主进程。请注意,在进程之间来回发送数据的开销可能会超过运行多个进程的优势。
  • 谢谢巴里,我愿意接受建议!有更好的解决方案吗?我是个新手!

标签: python pandas multiprocessing


【解决方案1】:

您必须从 processor 函数返回 summOut 并将值存储在列表中(此处为 data)。之后,您可以将summOut 的列表转换为您的数据框summaryDF。你可以这样做:

def processor(combin):
    ...
    return summOut


if __name__ == '__main__':
    with multiprocessing.Pool() as pool:
        data = pool.map(processor, combList)
        summaryDF = pd.DataFrame(data)

【讨论】:

  • 您好 Corralien 感谢您的解决方案!这会一遍又一遍地覆盖summaryDF吗? summaryDF = summaryDF.append(data) 会起作用吗?
  • 不,summaryDF 将在计算结束时创建一次。此外,在这种情况下,代码中summaryDF = pd.DataFrame(columns=['ModelID',...]) 的第一个声明是没有用的。
猜你喜欢
  • 1970-01-01
  • 2018-12-30
  • 2015-06-19
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2020-07-11
相关资源
最近更新 更多