我有一个包含1000万行的数据帧。每一行的迭代和计算花费了太多时间。我希望在更短的时间内得到结果。我尝试了不同的多处理代码,但每次都会遇到不同的错误。有人能帮我吗。提前谢谢。
d3是具有超过1000万行和29列的数据帧。最后一列的名称为"Calculation",此列中的所有值均为零。通过使用其他列的值,我计算了新值,并为"计算"列的每一行设置了新值。
第一个代码
def fun():
for i in d3.index:
if (d3.iloc[i, 3:4])[0] == (d3.iloc[i + 1, 3:4])[0]:
d3.loc[d3.index[i], 'Calculation']==(d3.iloc[i, 22:23] - d3.iloc[i + 1, 22:23])
else:
d3.loc[d3.index[i],'Calculation']=d3.iloc[i, 13:14][0]
if __name__=="__main__":
p1 = mp.Process(target=fun, args=())
p2 = mp.Process(target=fun, args=())
p3 = mp.Process(target=fun, args=())
p4 = mp.Process(target=fun, args=())
p1.start()
p2.start()
p3.start()
p4.start()
第二个代码
def fun(i):
if (d3.iloc[i, 3:4])[0] == (d3.iloc[i + 1, 3:4])[0]:
d3.set_value(i, "Calculation", (d3.iloc[i, 22:23] - d3.iloc[i + 1, 22:23]))
else:
d3.set_value(i, "Calculation", d3.iloc[i, 13:14])
if __name__=="__main__":
p1 = mp.Process(target=fun, args=(d3.index, ))
p2 = mp.Process(target=fun, args=(d3.index, ))
p3 = mp.Process(target=fun, args=(d3.index, ))
p4 = mp.Process(target=fun, args=(d3.index, ))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
第三个代码
def fun(q):
for i in d3.index:
if (d3.iloc[i, 3:4])[0] == (d3.iloc[i + 1, 3:4])[0]:
d3.loc[d3.index[i], 'Calculation']==(d3.iloc[i, 22:23] - d3.iloc[i + 1, 22:23])
else:
d3.loc[d3.index[i], 'Calculation']==(d3.iloc[i, 22:23] - d3.iloc[i + 1, 22:23])
q.put(d3)``
if __name__ == "__main__":
q = mp.Queue()
processes = [mp.Process(target=fun, args=(q,)) for x in range(4)]
for p in processes:
p.start()
for p in processes:
p.join()
results = [q.get() for p in processes]
错误1:
File "pandas_libsops.pyx", line 103, in pandas._libs.ops.vec_compare
ValueError: Buffer has wrong number of dimensions (expected 1, got 0)
错误2:
File "pandas_libshashtable_class_helper.pxi", line 1614, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 0
错误3:
File "pandas_libsops.pyx", line 103, in pandas._libs.ops.vec_compare
ValueError: Buffer has wrong number of dimensions (expected 1, got 0)
在第三个示例中,您需要将q和d3都传递给子进程。在场景中发生的情况是,如果fun(q,d3(修改d3,则d3在被修改之前被复制到专用于运行fun(q、d3(的子进程的内存空间中。如果在子进程中不修改d3,则子进程仅保留来自父进程的对d3的引用(这是有效的(。
现在,如果d3非常大,并且您希望减少运行时间和内存需求,我只会将对d3的引用传递给您的4个子进程(即,不要在子进程中修改d3以避免复制(,以及开始和停止行索引。然后fun(d3,q,start_idx,stop_idx(只会返回一个长度列表stop_idx-start_idx,您的父进程稍后会将其放回名为Calculation的原始d3列中。