Java 基于列和条件的数据匹配
我有两个包含数百万行的数据集。示例如下所示: 数据集1:Java 基于列和条件的数据匹配,java,python,scala,pyspark,julia,Java,Python,Scala,Pyspark,Julia,我有两个包含数百万行的数据集。示例如下所示: 数据集1: Row col1 col2 col3 1 A 01-01-1991 10 2 B 02-01-1991 20 数据集2: Row col1 col2 col3 1 A 01-01-1991 -10 2 B 02-01-1991 -10 3 B 01-01-1991 -10 我想根据col1,co
Row col1 col2 col3
1 A 01-01-1991 10
2 B 02-01-1991 20
数据集2:
Row col1 col2 col3
1 A 01-01-1991 -10
2 B 02-01-1991 -10
3 B 01-01-1991 -10
我想根据col1,col2匹配行-公差为1天,如果col3之和等于零,则根据数据生成唯一的id
因此,根据上述规则,最终结果应如下所示:
Data_set Row col1 col2 col3 Group_Id
1 1 A 01-01-1991 -10 1
2 1 A 01-01-1991 10 1
1 2 B 02-01-1991 20 2
1 2 B 02-01-1991 -10 2
1 3 B 01-01-1991 -10 2
我不想任何代码,但想法。我请求你们给我指出一个好的逻辑,以便在大数据集上实现这一点。我愿意使用Julia、pyspark或scala
我试过一种逻辑:
在col1和col2上聚合数据库,然后从这两个数据集中添加col3。这包括组id 1,但组2不属于此范围。因此julia有一个,但这不适用于日期
但是,您可以只减去日期,然后检查差值是否小于1
using Dates
x = Date(2016, 07, 16)
y = Date(2016, 07, 13)
abs( x - y ) # 3 days
abs(x - y) <= Day(1) # false
或者,无论什么逻辑,在每个数据库中每行需要有两行,这是很常见的…您的主要问题是与日期的逻辑比较。我建议您将日期转换为朱利安日期格式。这里有一些Mathematica的代码可以帮助您
ToJulianDayNumber[date_List] := Module[
{year = date[[1]],
month = date[[2]],
day = date[[3]],
a,
y,
m,
result},
a = Quotient[ 14 - month, 12 ];
y = year + 4800 - a;
m = month + 12 * a - 3;
result =
day + Quotient[ 153* m + 2, 5 ] + 365 * y +
Quotient[ y, 4 ] - Quotient[ y, 100 ] +
Quotient[ y, 400 ] - 32045;
result
]
FromJulianDayNumber[juliandaynum_Integer] := Module[
{gnum, dgnum, cnum, dcnum, bnum,
dbnum, anum, danum, ynum, mnum, dnum,
yyyy, mm, dd, jnum, result},
jnum = juliandaynum + 32044;
gnum = Quotient[ jnum, 146097 ];
dgnum = Mod[ jnum, 146097 ];
cnum = (Quotient[ dgnum, 36524 ] + 1 ) * 3;
cnum = Quotient[ cnum, 4 ];
dcnum = dgnum - (cnum * 36524);
bnum = Quotient[ dcnum, 1461 ];
dbnum = Mod[ dcnum, 1461 ];
anum = (Quotient[ dbnum, 365 ] + 1 ) * 3;
anum = Quotient[ anum, 4 ];
danum = dbnum - (anum * 365);
ynum = gnum * 400 + cnum * 100 + bnum * 4 + anum;
mnum = Quotient[(danum*5 + 308), 153] - 2;
dd = danum - Quotient[ (mnum + 4)*153, 5 ] + 123;
yyyy = ynum - 4800 + Quotient[ mnum + 2, 12 ];
mm = Mod[ mnum + 2, 12 ] + 1;
Return[{yyyy, mm, dd}]
]
一旦您将日期转换为整数,您就可以更轻松地进行任意比较。还不完全清楚您有哪些限制条件。但是,如果您可以在col1
和col2
上对数据集1和数据集2进行排序(在Julia中,您可以这样做,例如,如果数据太大而无法放入RAM,则可以使用JuliaDB),然后编写一个循环,在这两个集合上迭代以生成连续的组。为了实现这一点,不需要将整个数据集加载到RAM中,也不需要将结果存储在RAM中。Thx@BogumiłKamiński供评论,但如何捕获日期容差?还有python中merge_asof()的Julia等价物吗?正如我所建议的,如果您有不适合内存的大数据,请使用while
在两个表上循环并移动光标,跟踪每个表中两天窗口的开始和结束。@BogumiłKamińjuliadb是一个不错的选择。我在尝试filter函数,但我一直得到以下错误:错误:MethodError:没有方法匹配convert(::Type{Array{Bool,1}},::PooledArray.PooledArray{Boo l,UInt8,1,Array{UInt8,1},::Bool)这可能是由于调用构造函数数组{Bool,1}(…),因为类型构造函数会返回到转换方法。。。。我正在尝试对col1进行筛选…筛选(x->x==“A”,DataA,select=:col1)如果您发布一个关于此错误的单独问题,并使用最小的可重复代码,可能会更好,因为现在很难诊断。您的解决方案假设逐行匹配,特别是两个数据集的行数相同——如果我正确理解问题的话——情况并非如此。另外,DataFrame
只有在数据很小的情况下才是一个好的解决方案(我从问题描述中了解到,数据不适合RAM)。对于逐行注释,这是正确的,我也说过很多。即使比较逻辑更复杂,预分配也可能是有益的,因为添加新行的开销很容易超过比较/col3逻辑。此外,数据帧确实会耗尽内存。但是,这里和那里的几百万可以很容易地放入大多数RAM中,即使是在笔记本电脑上。但考虑到这一点,。
C = DataFrame([Int, Int, Char, Date, ...], [:dataset, :row, :date, ...], sum(validrows))
for i in findall(validrows)
C[i, :] = ... # your magic here
end
ToJulianDayNumber[date_List] := Module[
{year = date[[1]],
month = date[[2]],
day = date[[3]],
a,
y,
m,
result},
a = Quotient[ 14 - month, 12 ];
y = year + 4800 - a;
m = month + 12 * a - 3;
result =
day + Quotient[ 153* m + 2, 5 ] + 365 * y +
Quotient[ y, 4 ] - Quotient[ y, 100 ] +
Quotient[ y, 400 ] - 32045;
result
]
FromJulianDayNumber[juliandaynum_Integer] := Module[
{gnum, dgnum, cnum, dcnum, bnum,
dbnum, anum, danum, ynum, mnum, dnum,
yyyy, mm, dd, jnum, result},
jnum = juliandaynum + 32044;
gnum = Quotient[ jnum, 146097 ];
dgnum = Mod[ jnum, 146097 ];
cnum = (Quotient[ dgnum, 36524 ] + 1 ) * 3;
cnum = Quotient[ cnum, 4 ];
dcnum = dgnum - (cnum * 36524);
bnum = Quotient[ dcnum, 1461 ];
dbnum = Mod[ dcnum, 1461 ];
anum = (Quotient[ dbnum, 365 ] + 1 ) * 3;
anum = Quotient[ anum, 4 ];
danum = dbnum - (anum * 365);
ynum = gnum * 400 + cnum * 100 + bnum * 4 + anum;
mnum = Quotient[(danum*5 + 308), 153] - 2;
dd = danum - Quotient[ (mnum + 4)*153, 5 ] + 123;
yyyy = ynum - 4800 + Quotient[ mnum + 2, 12 ];
mm = Mod[ mnum + 2, 12 ] + 1;
Return[{yyyy, mm, dd}]
]