从spark数据帧中的多个重复行中删除第一个

时间:2016-08-24 11:12:45

标签: scala apache-spark

我有一个与此类似的DataFrame

+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+-----+
    |     disc_created_dt|    disc_modified_dt|        disc_line_id|         quarter_num|         period_year|          start_date|            end_date| test|
    +--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+-----+
    |2012-05-31 10:50:...|2016-03-12 10:41:...|138371.0000000000...|4.000000000000000000|2012.000000000000...|2012-05-27 09:30:...|2012-06-23 09:30:...|42012|
    |2011-09-27 03:40:...|2016-03-12 10:39:...|141773.0000000000...|1.000000000000000000|2012.000000000000...|2011-09-25 09:30:...|2011-10-29 09:30:...|12012|
    |2011-06-22 02:41:...|2016-03-12 10:40:...|59374.00000000000...|4.000000000000000000|2011.000000000000...|2011-05-29 09:30:...|2011-06-25 09:30:...|42011|
    |2012-02-24 23:46:...|2016-03-12 10:39:...|272176.0000000000...|3.000000000000000000|2012.000000000000...|2012-01-29 10:30:...|2012-02-25 10:30:...|32012|
    |2012-09-16 15:02:...|2016-03-12 10:42:...|450778.0000000000...|1.000000000000000000|2013.000000000000...|2012-08-26 09:30:...|2012-09-22 09:30:...|12013|
    +--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+-----+

disc_line_id可以包含重复值。 有2个要求:

  1. 我想要使用dropDuplicates命令基于disc_line_idcreated_date只有1条记录。

  2. 我希望所有记录除了modified_date disc_line_id之外的所有记录<{1}}

  3. 如果两者都可以在单一转换中完成,那就太棒了。

    示例

    disc_line_id|created_date|modified_date
    1             2016-08-24  2016-08-24
    1             2016-08-21  2016-08-21
    1             2016-08-21  2016-08-24
    2             2016-08-23  2016-08-24
    3             2016-08-22  2016-08-22
    3             2016-08-22  2016-08-23
    3             2016-08-22  2016-08-24
    

    对于我想要的数据帧

    要求1(每个光盘行ID基于创建日期):

     disc_line_id|created_date|modified_date
        1             2016-08-21  2016-08-21
        2             2016-08-23  2016-08-24
        3             2016-08-22  2016-08-22
    

    Req 2(每个光盘行ID基于修改日期):

     disc_line_id|created_date|modified_date
        1             2016-08-24  2016-08-24
        1             2016-08-21  2016-08-24
        3             2016-08-22  2016-08-23
        3             2016-08-22  2016-08-24
    

    我是新手,火花和scala任何帮助将不胜感激。 spark版本1.4.1

1 个答案:

答案 0 :(得分:1)

由于缺少子查询,您必须将其分解为几个步骤。

首先,您需要选择行ID和最大日期(如果您想要最新的)。这样做(假设您的数据位于名为df的数据框中)

val tmp = df.select("disk_line_id","created_date").groupBy("disk_line_id").max("created_date").withColumnRenamed("disk_line_id", "line_id")
val theNewest = tmp.join(df,tmp("max(created_date)")===df("created_date") && tmp("line_id")===df("disk_line_id")).drop("max(created_date)").drop("line_id")

然后为了获得除了之外的所有内容:

val theRest = df.except(theNewest)

上面的代码是半伪代码,因为我不记得Spark是否允许你在约会时做max()。您可能需要将日期转换为时间戳才能执行上述代码。