假设我有一个大内存numpy数组,我有一个函数func,它接受这个巨大的数组作为输入(连同一些其他参数).func具有不同参数可以并行运行.例如:
def func(arr, param):
# do stuff to arr, param
# build array arr
pool = Pool(processes = 6)
results = [pool.apply_async(func, [arr, param]) for param in all_params]
output = [res.get() for res in results]
Run Code Online (Sandbox Code Playgroud)
如果我使用多处理库,那么这个巨型数组将被多次复制到不同的进程中.
有没有办法让不同的进程共享同一个数组?此数组对象是只读的,永远不会被修改.
更复杂的是,如果arr不是一个数组,而是一个任意的python对象,有没有办法分享它?
[EDITED]
我读了答案,但我仍然有点困惑.由于fork()是copy-on-write,因此在python多处理库中生成新进程时不应调用任何额外的成本.但是下面的代码表明存在巨大的开销:
from multiprocessing import Pool, Manager
import numpy as np;
import time
def f(arr):
return len(arr)
t = time.time()
arr = np.arange(10000000)
print "construct array = ", time.time() - t;
pool = Pool(processes = 6)
t = …Run Code Online (Sandbox Code Playgroud) python parallel-processing numpy shared-memory multiprocessing
我更精确地使用Python多处理
from multiprocessing import Pool
p = Pool(15)
args = [(df, config1), (df, config2), ...] #list of args - df is the same object in each tuple
res = p.map_async(func, args) #func is some arbitrary function
p.close()
p.join()
Run Code Online (Sandbox Code Playgroud)
这种方法具有巨大的内存消耗; 几乎占用了我所有的RAM(此时它变得非常慢,因此使多处理非常无用).我假设问题是这df是一个巨大的对象(一个大型的pandas数据帧),它会被复制到每个进程.我试过使用multiprocessing.Value共享数据帧而不复制
shared_df = multiprocessing.Value(pandas.DataFrame, df)
args = [(shared_df, config1), (shared_df, config2), ...]
Run Code Online (Sandbox Code Playgroud)
(正如Python多处理共享内存中所建议的那样),但是这给了我TypeError: this type has no size(与在Python进程之间共享一个复杂对象相同?,遗憾的是我不理解答案).
我第一次使用多处理,也许我的理解还不够好.是multiprocessing.Value实际上即使在这种情况下使用了正确的事情?我已经看到了其他建议(例如队列),但现在有点困惑.有什么选择可以共享内存,在这种情况下哪一个最好?
我还处于 Python 学习的早期阶段。如果这个问题听起来很愚蠢,请提前道歉。
我有这组数据(表格格式),我想向其中添加几个计算列。基本上我有一些位置 lon/lat 和目的地 lon/lat,以及各自的数据时间,我正在计算每对之间的平均速度。
示例数据如下所示:
print(data_all.head(3))
id lon_evnt lat_evnt event_time \
0 1 -179.942833 41.012467 2017-12-13 21:17:54
1 2 -177.552817 41.416400 2017-12-14 03:16:00
2 3 -175.096567 41.403650 2017-12-14 09:14:06
dest_data_generate_time lat_dest lon_dest \
0 2017-12-13 22:33:37.980 37.798599 -121.292193
1 2017-12-14 04:33:44.393 37.798599 -121.292193
2 2017-12-14 10:33:51.629 37.798599 -121.292193
address_fields_dest \
0 {'address': 'Nestle Way', 'city': 'Lathrop...
1 {'address': 'Nestle Way', 'city': 'Lathrop...
2 {'address': 'Nestle Way', 'city': 'Lathrop...
Run Code Online (Sandbox Code Playgroud)
然后我将 lon/lat 压缩在一起:
data_all['ping_location'] = list(zip(data_all.lon_evnt, data_all.lat_evnt))
data_all['destination'] = …Run Code Online (Sandbox Code Playgroud)