此处是新手式python / pandas用户。我一直在read_fwf中使用chunksize arg并迭代变量的value_counts。我编写了一个函数来传递args(例如fileiterator)和变量以进行解析和计数。我希望能够并行化此功能,并且能够同时将2个文件读取到同一功能中。 它的确起作用了……但是,我的速度变慢了。线程同时完成,但是一个似乎正在减慢另一个(IO瓶颈?)。通过顺序而不是并行运行这些功能,我得到了更快的速度(324秒对172秒)。有想法吗?我执行错了吗?我已经尝试了多进程,但是出现了startmap错误,无法使fileiterator(read_fwf的输出)腌制。
testdf1=pd.read_fwf(filepath_or_buffer='200k.dat',header=None,colspecs=wlist,names=nlist,dtype=object,na_values=[''],chunksize=1000)
testdf2=pd.read_fwf(filepath_or_buffer='200k2.dat',header=None,colspecs=wlist,names=nlist,dtype=object,na_values=[''],chunksize=1000)
def tfuncth(df,varn,q,*args):
td={}
for key in varn.keys():
td[key]=pd.Series()
for rdf in df:
if args is not None:
for arg in args:
rdf=eval(f"rdf.query(\"{arg}\")")
for key in varn.keys():
ecode=f'rdf.{varn[key]}.value_counts()'
td[key]=pd.concat([td[key],eval(ecode)])
td[key]=td[key].groupby(td[key].index).sum()
for key in varn.keys():
td[key]=pd.DataFrame(td[key].reset_index()).rename(columns={'index':'Value',0:'Counts'}).assign(Var=key,PCT=lambda x:round(x.Counts/x.Counts.sum()*100,2))[['Var','Value','Counts','PCT']]
q.put(td)
bands={
'1':'A',
'2':'B',
'3':'C',
'4':'D',
'5':'E',
'6':'F',
'7':'G',
'8':'H',
'9':'I'
}
vdict={
'var1':'e1270.str.slice(0,2)',
'var2':'e1270.str.slice(2,3)',
'band':'e7641.str.slice(0,1).replace(bands)'
}
my_q1=queue.Queue()
my_q2=queue.Queue()
thread1=threading.Thread(target=tfuncth,args=(testdf1,vdict,my_q1,flter1))
thread2=threading.Thread(target=tfuncth,args=(testdf2,vdict,my_q2))
thread1.start()
thread2.start()
更新:
大量阅读后,这也是我得出的结论。我确信这是极其简化的结论,所以如果有人知道,请通知我。
Pandas不是完全多线程友好的软件包
Python并不是真正的多线程兼容语言 情况
答案 0 :(得分:0)
我确实设法通过使用多处理程序包使它工作并解决了我的问题。我遇到了两个问题。
1)多处理程序包与Juypter Notebook不兼容
和
2)您不能腌制熊猫阅读器的句柄(将多重处理的腌制对象传递给进程)。
我通过在Notebook环境之外进行编码来固定1,并通过向每个进程传递打开分块文件所需的参数来固定2,并让每个进程开始读取自己的块。
完成这两项操作后,与顺序运行相比,我的速度提高了60%。