从类对象

时间:2015-09-17 14:44:38

标签: pandas python-multiprocessing

我正在使用多处理模块生成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。但不会返回任何东西。

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

2 个答案:

答案 0 :(得分:3)

在您的情况下,我更愿意尽可能少地编写代码并使用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 ':('

答案 1 :(得分: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