所以我的问题可能是天真的,但我一直在寻找,我仍然找不到答案。我有两个大数据集:
Lastname Census 1stname Census census_year
C2last C2first 1880
C3last C3first 1850
C4last C4first 1850
Lastname Reg 1stname reg birth_year
P2Last P2first 1818
P3last P3first 1879
P4last P4first 1903
我需要执行两个数据集的笛卡尔积,这显然是一个巨大的文件(700,000 x 80,000),对于人口普查的每一行,我们应该添加80,000个民用寄存器和一个额外的变量。
此额外变量的值满足条件。条件是人口普查年(人口普查的变量)大于民事登记册的变量“出生年份”(换句话说,人口普查年份比登记册上的出生年龄小)。
正如我所说,目标是制作笛卡尔积,但增加一个额外的变量(旗帜),当条件满足时(人口普查年份>出生年份)给出'1'或'0',当它不是:
LastNCens 1stNCens cens_year LastNamReg 1stNamReg birth Flag
C2last C2first 1880 P2Last P2first 1818 1
P3last P3first 1879 1
P4last P4first 1903 0
C3last C3first 1850 P2Last P2first 1818 1
P3last P3first 1879 0
P4last P4first 1903 0
C4last C4first 1860 P2Last P2first 1818 1
P3last P3first 1879 0
P4last P4first 1903 0
所有这一切,请记住产品太大了。
我尝试过很多东西(比较,差异,交叉),我也读过其他我不能应用的东西(df.where
,pd.merge
),但它们没有做我需要的东西,我不能在这里使用它们。我的简单方法是:
cp <- merge(census, register,by=NULL);
final.dataframe <- cp [which (cp$census_year > cp$birth_year_hsn ),]
但是R耗尽内存。
毫无疑问,结果数据框(笛卡尔积)也只对那些标记为'1'的记录有效(摆脱那些带有Flag='0'
的记录)。
我希望这个解释得很好,对其他人也很有用......万分感谢任何提示。非常欢迎。
随着对问题的评论,你可以使用data.table
包来实现你想要的东西。该包通过引用进行修改,因此可以帮助减少用于子集,合并和计算的内存量。有关该软件包的更多信息,我建议使用他们的wikipedia github page,其中包含大多数计算的快速备忘单。
下面是一个如何使用data.table执行您正在寻找的合并类型的示例。它被称为non-equi join
。几点说明。似乎data.table
包中存在一个错误,尚未被注意到。当您输出两个连接列时,by = .EACHI
似乎是必要的,以便获得连接左侧部分的原始值。然而,这是一个很小的成本。
df1 <- fread("Lastname_Census firstname_Census census_year
C2last C2first 1880
C3last C3first 1850
C4last C4first 1850", key = "census_year")
df2 <- fread("Lastname_Reg firstname_reg birth_year
P2Last P2first 1818
P3last P3first 1879
P4last P4first 1903", key = "birth_year")
cart_join <-
df2[df1, #join df1 on df2
on = .(birth_year >= census_year), #join criteria
#Force keep all columns to keep (i.var, indicates to keep var from df1)
j = .(i.Lastname_Census,
i.firstname_Census,
Lastname_Reg,
firstname_reg,
birth_year,
i.census_year,
Flag = birth_year >= i.census_year),
#Force evaluation on each i. This will keep the correct birth_year (seems to be a bug)
by = .EACHI,
#Let the table grow beyond nrow(df1) + nrow(df2)
allow.cartesian = TRUE][,-1] #Remove the first column. It is a merge column
在玩了这个连接之后,我注意到了一些违规行为,然后开了一个问题here。请注意,您应该小心我的上述建议的答案。从两个表中返回值(除了在on
语句中使用过的值)之外,它似乎工作正常,但它并不是难以理解的。有关更多信息,请参阅我的open issue。