【发布时间】:2019-12-12 02:33:42
【问题描述】:
我创建了一个 pandas 数据框的全局变量。我希望子进程可以访问全局数据框,但似乎子进程无法获取全局变量。
data = pd.DataFrame(data = np.array([[i for i in range(1000)] for j in range(500)]))
def get_sample(i):
print("start round {}".format(i))
sample = data.sample(500, random_state=i)
xs = sample.sum(axis=0)
if i < 10:
print(data.shape())
print(sample.iloc[:3, :3])
print("rount{} returns output".format(i))
return xs
samples = []
def collect(result):
print("collect called with {}".format(result[0][0].shape))
global samples
samples.extend(result)
ntasks = 1000
if __name__=='__main__':
samples = []
xs = pd.DataFrame()
"""sampling"""
pool = mp.Pool(cpu_count(logical=True))
print("start sampling, total round = {}".format(ntasks))
r = pool.map_async(get_sample, [j for j in range(ntasks)], callback=collect)
r.wait()
pool.close()
pool.join()
xs = pd.concat([sample for sample in samples], axis = 1, ignore_index=True)
xs = xs.transpose()
print("xs: ")
print(xs.shape)
print(xs.iloc[:10, :10])
全局数据框是数据。我期望在每个子进程中,函数 get_sample 可以访问数据并从数据中检索一些值。为了确保子进程可以获取数据,我在每个子进程中打印出数据的形状。问题是子进程似乎无法获取数据,因为当我运行它时,既没有打印出数据的形状,也没有打印出部分样本。
此外,我收到错误: 回溯(最近一次通话最后): 文件“sampling2c.py”,第 51 行,在 xs = pd.concat([sample for sample in samples], axis = 1, ignore_index=True) 文件“/usr/usc/python/3.6.0/lib/python3.6/site-packages/pandas/tools/merge.py”,第 1451 行,在 concat 复制=复制) init 中的文件“/usr/usc/python/3.6.0/lib/python3.6/site-packages/pandas/tools/merge.py”,第 1484 行 raise ValueError('没有要连接的对象') get_sample 函数似乎没有返回任何内容,采样失败。
但是,当我做了一个实验来测试子进程是否可以访问全局变量时,它起作用了。
df = pd.DataFrame(data = {'a':[1,2,3], 'b':[2,4,6]})
df['c1'] = [1,2,1]
df['c2'] = [2,1,2]
df['c3'] = [3,4,4]
df2 = pd.DataFrame(data = {'a':[i for i in range(100)], 'b':[i for i in range(100, 200)]})
l = [1, 2, 3]
Mgr = Manager()
results = []
def collect(result):
global results
#print("collect called with {}".format(result))
results.extend(result)
counter = 12
def sample(i):
print(current_process())
return df2.sample(5, random_state = i)
if __name__=='__main__':
pool = Pool(3)
r = pool.map_async(sample, [i for i in range(3)], callback = collect) #callback = collect
r.wait()
for res in results:
print(res)
每个子进程都可以访问全局变量df2。我不确定为什么子进程无法访问第一个代码块中的数据。
【问题讨论】:
-
Multiprocessing 根据现有答案stackoverflow.com/questions/659865/… 使用自己的新全局生成新进程
-
子进程只有每个变量的虚拟副本。父母或孩子所做的更改不会被另一方看到。