我正在尝试将字符串转换为日期时间对象。这些字符串存储在 csv 列中。文件很大,我想多处理它。
我的代码看起来像这样:
def conv_datetime(file):
return ([pd.to_datetime(j[3]) for j in file])
if __name__ == "__main__":
n = 0
file = pd.read_csv("csv_file",header=None,chunksize=200,skiprows=n)
n += 200
pro = mp.Process(target=conv_datetime,args=(file,))
pro.deamon = False
pro.start()
pro.join()
我得到 :
AttributeError
Traceback (most recent call last)
<ipython-input-1-5d16d82af0d2> in <module>()
15 pro = mp.Process(target=conv_datetime,args=(file,))
16 pro.deamon = False
---> 17 pro.start()
18 pro.join()
19
C:ProgramDataAnaconda33libmultiprocessingprocess.py in start(self)
103 'daemonic processes are not allowed to have children'
104 _cleanup()
--> 105 self._popen = self._Popen(self)
106 self._sentinel = self._popen.sentinel
107 # Avoid a refcycle if the target function holds an indirect
C:ProgramDataAnaconda33libmultiprocessingcontext.py in _ Popen(process_obj)
221 @staticmethod
222 def _Popen(process_obj):
--> 223 return _default_context.get_context().Process._Popen(process_obj)
224
225 class DefaultContext(BaseContext):
C:ProgramDataAnaconda33libmultiprocessingcontext.py in _Popen(process_obj)
320 def _Popen(process_obj):
321 from .popen_spawn_win32 import Popen
--> 322 return Popen(process_obj)
323
324 class SpawnContext(BaseContext):
C:ProgramDataAnaconda33libmultiprocessingpopen_spawn_win32.py in __init__(self, process_obj)
63 try:
64 reduction.dump(prep_data, to_child)
---> 65 reduction.dump(process_obj, to_child)
66 finally:
67 set_spawning_popen(None)
C:ProgramDataAnaconda33libmultiprocessingreduction.py in dump(obj, file, protocol)
58 def dump(obj, file, protocol=None):
59 '''Replacement for pickle.dump() using ForkingPickler.'''
---> 60 ForkingPickler(file, protocol).dump(obj)
61
62 #
AttributeError: Can't pickle local object '_make_date_converter.<locals>.converter'
在有人给我代码解决方案之前,如果可以深入了解守护进程的工作原理,那将非常有帮助。
如果你看一下multiprocessing/process.py
代码(你似乎没有使用Python 3.6,所以行号有点不同,但这部分代码是不变的),你可以很清楚地看到关于守护进程的字符串是不相关的; 这只是您的代码设法通过而没有任何问题的assert
的一部分, 在几行之后由于完全不相关的原因失败之前。
实际问题出在第 105 行,错误消息中对此进行了说明:
AttributeError: Can't pickle local object '_make_date_converter.<locals>.converter'
您正在尝试将对象传递给无法酸洗的子进程。这在multiprocessing
文档中进行了一些解释,例如,在编程指南下,尽管这些文档假设您理解"pickle"的含义,并且您已经阅读了文档的相当多的早期部分。您确实应该阅读前面的部分,并在文档中查找pickle
,但基本思想是这样的:
multiprocessing
模块使用pickle
模块将参数传递给函数、从函数返回值、将值放在队列中等。pickle
模块只能处理设计为可选取的数据类型。因此,某些类型不能与multiprocessing
一起传递。
在这种情况下,应该有一个非常简单的解决方法:只需传递文件名,然后让子进程读取它。当然,这不适用于更复杂的情况,但如果它适用于您的情况,请保持简单。
对于更复杂的情况,Pandas 的通常解决方案是用第三方库(如dill
或cloudpickle
)替换标准拾取器,这些库更了解 Pandas 并可以强制其成形以通过网络。(或者,有时,将multiprocess
本身替换为第三方库,如dask
。这并不难学,但你确实需要查看选项,选择一个,并阅读如何挂钩它,如果不需要,你可能不想这样做。
如果您仍然对守护进程感兴趣,请参阅参考文档中的进程。但简短的版本是,在这种情况下,守护进程是一个不被join
编辑的进程 - 换句话说,你不会像普通进程那样等待它在主进程完成时完成。