【问题标题】:return a list from class object从类对象返回一个列表
【发布时间】:2015-09-17 14:44:38
【问题描述】:

我正在使用多处理模块来生成 35 个数据帧。我想这会节省我的时间。但问题是该类不返回任何东西。我希望从 self.dflist 返回数据帧列表

这是创建 dfnames 列表的方法。

urls=[]
fnames=[]
dfnames=[]
for x in xrange(100,3600,100):
    y = str(x)
    i = y.zfill(4)
    filename='DCHB_Town_Release_'+i+'.xlsx'
    url = "http://www.censusindia.gov.in/2011census/dchb/"+filename
    urls.append(url)
    fnames.append(filename)
    dfnames.append((filename, 'DCHB_Town_Release_'+i))

这是使用上面代码生成的dfnames的类。

import pandas as pd
import multiprocessing
class mydf1():
    def __init__(self, dflist, jobs, dfnames):
        self.dflist=list()
        self.jobs=list()
        self.dfnames=dfnames
    def dframe_create(self, filename, dfname):
        print 'abc', filename, dfname
        dfname=pd.read_excel(filename)
        self.dflist.append(dfname)
        print self.dflist
        return self.dflist

    def mp(self):
        for f,d in self.dfnames:
            p = multiprocessing.Process(target=self.dframe_create, args=(f,d))
            self.jobs.append(p)
            p.start()
        #return self.dflist

        for j in self.jobs:
            j.join()
            print '%s.exitcode = %s' % (j.name, j.exitcode)

这样调用的类...

dflist=[]
jobs=[]
x=mydf1(dflist, jobs, dfnames)
y=x.mp()

正确打印 self.dflist。但不返回任何东西。

我可以按顺序收集所有数据场。但为了节省时间,我需要同时使用多个进程来生成数据帧并将其添加到列表中。

【问题讨论】:

    标签: pandas python-multiprocessing


    【解决方案1】:

    在您的情况下,我更喜欢编写尽可能少的代码并使用Pool

    import pandas as pd
    import logging
    import multiprocessing
    
    def dframe_create(filename):
        try:
             return pd.read_excel(filename)
        except Exception as e:
             logging.error("Something went wrong: %s", e, exc_info=1)
             return None
    
    p = multiprocessing.Pool()
    
    excel_files = p.map(dframe_create, dfnames)
    for f in excel_files:
          if f is not None:
                print 'Ready to work'
          else:
                print ':('
    

    【讨论】:

    • 如何知道流程是否成功完成?是否有类似问题中显示的 j.exitcode 的方法?
    • @shantanuo,如果发生某些事情,进程将引发异常,但这是罕见的事件。 dframe_create 函数中的异常很可能出现,因此,您可以添加try-except 并检查None 的结果。我在回答中做了一些更改以展示这种方法。
    【解决方案2】:

    正确打印 self.dflist。但不返回任何东西。

    那是因为你在mp 方法中没有返回语句,例如

    def mp(self):
        ...
        return self.dflist
    

    尚不完全清楚您的问题是什么,但是,您必须在此处小心,因为您不能只是跨进程传递对象/列表。这就是为什么你有特殊的对象(当它们对列表进行修改时锁定),这样当两个进程尝试同时进行更改时你不会被绊倒(你只会得到一个更新)。

    也就是说,你必须使用multiprocessing's list

    class mydf1():
        def __init__(self, dflist, jobs, dfnames):
            self.dflist = multiprocessing.list()  # perhaps should be multiprocessing.list(dflist or ())
            self.jobs = list()
            self.dfnames = dfnames
    

    但是您有一个更大的问题:多处理的全部意义在于它们可能会乱序运行/完成,因此像这样保留两个列表注定要失败。您应该使用 multiprocessing.dict 这样 DataFrame 会与文件名一起明确保存。

    class mydf1():
        def __init__(self, dflist, jobs, dfnames):
            self.dfdict = multiprocessing.dict()
            ...
    
        def dframe_create(self, filename, dfname):
            print 'abc', filename, dfname
            df = pd.read_excel(filename)
            self.dfdict[dfname] = df
    

    【讨论】:

      猜你喜欢
      • 2020-05-15
      • 2022-07-27
      • 1970-01-01
      • 2021-03-01
      • 2016-08-30
      • 1970-01-01
      • 2014-10-15
      • 2014-03-18
      • 1970-01-01
      相关资源
      最近更新 更多