根据列和条件进行数据匹配

时间:2018-09-09 04:48:49

标签: 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,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不属于该组。

2 个答案:

答案 0 :(得分:0)

因此julia有一个isapporx function,但不适用于Dates

但是,您可以减去日期并检查差值是否小于1。

using Dates
x = Date(2016, 07, 16)
y = Date(2016, 07, 13)
abs( x - y ) # 3 days
abs(x - y) <= Day(1) # false

对于大型数据集,您可能希望先通过查找新数据表有多少条目,然后填写(即数据的两次通过算法)来预先分配新数据表

using DataFrames
A = ... # dataframe 1
B = ... # dataframe 2
f(a::Date, b::Date) = abs(a-b) <= Day(1)
validrows = f.(A[:col2], B[:col2]) # a bitarray
sum(validrows) # number of rows that are within a day of each other

这假设您只是将数据集1中的行i与数据集2中的行i进行比较。 然后,您可以遍历两者的行,并将它们“导入”到datset 3

C = DataFrame([Int, Int, Char, Date, ...], [:dataset, :row, :date, ...], sum(validrows))
for i in findall(validrows)
   C[i, :] = ... # your magic here 
end

或者您需要在每个数据库中每行具有两行的逻辑是什么……

答案 1 :(得分:0)

您的主要问题是与日期进行逻辑比较。我建议您将日期转换为儒略日期格式。这是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}]
  ]

将日期转换为整数后,无论如何您都可以轻松进行比较。