我正在尝试将多个熊猫数据帧合并到具有字段[“ a_id”,“ b_id”,“ c_id”]的大型Dask数据帧中。每个熊猫数据框“ A”,“ B”和“ C”都有一个唯一字段(“ a_id”,“ b_id”和“ c_id”)将其连接到Dask数据框。 “ B”和“ C”也具有字段“ b_Field1”:
import pandas as pd
import dask.dataframe as dd
A = pd.DataFrame({'a_id': [1, 2, 3], 'a_Field1': [0, 0, 0]})
B = pd.DataFrame({'b_id': [3, 4, 5], 'b_Field1': [7, 8, 9]})
C = pd.DataFrame({'c_id': [4, 5, 6], 'b_Field1': [6, 7, 8], 'c_Field1': [10, 11, 12]})
pdf = pd.DataFrame({'a_id': [1, 2], 'b_id': [3, 4], 'c_id': [5, 6]})
pdf = pdf.merge(A, how="left", on="a_id")
pdf = pdf.merge(B, how="left", on="b_id")
pdf = pdf.merge(C, how="left", on=["c_id", "b_Field1"])
print(pdf)
"""
Result:
a_id b_id c_id a_Field1 b_Field1 c_Field1
0 1 3 5 0 7 11
1 2 4 6 0 8 12
"""
dA = dd.from_pandas(A, npartitions=1)
dB = dd.from_pandas(B, npartitions=1)
dC = dd.from_pandas(C, npartitions=1)
ddf = dd.from_pandas(pdf, npartitions=1)
ddf = ddf.merge(dA, how="left", on="a_id")
ddf = ddf.merge(dB, how="left", on="b_id")
ddf = ddf.merge(dC, how="left", on=["c_id", "b_Field1"])
失败,表示ddf中没有字段“ b_Field1”。我的想法是我需要在合并B和C之间执行.compute()命令,但这会使Dask在进度条上无休止地挂40%(最终死于MemoryError)。
进行第二次连接之前,计算是否必要?如果是这样,它是否会挂起?这些数据集很小,不足以合并到纯熊猫中,并且合并很快发生,但是我试图将其部署在内存更少的机器上。
答案 0 :(得分:1)
如果您确实在最后一行之前检查了数据框,则会发现它具有以下列:
a_id b_id c_id a_Field1_x b_Field1_x c_Field1 a_Field1_y b_Field1_y
,即b_Field1
已分成两部分,实际上事实证明两者是相同的。正如您所展示的,这可能是Dask中的错误,因为在熊猫中不会发生相同的情况。但是,设置适当的索引或将可选的args调整为merge
可能是一种解决方法。
使用数据框,您可以完成
ddf = ddf.merge(dC.rename(columns={'b_Field1': 'b_Field1_x'}),
how="left", on=["c_id", "b_Field1_x"])
现在您还会在其中重复c_
列。
关于一般内存问题,在其他地方对此进行了详尽的讨论。请确保仔细选择分区大小,索引和工作人数。