Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较Java Spark数据框架中的日期_Java_Apache Spark - Fatal编程技术网

比较Java Spark数据框架中的日期

比较Java Spark数据框架中的日期,java,apache-spark,Java,Apache Spark,我有下面的Spark数据帧/数据集。列_2具有字符串格式的日期 Column_1 Column_2 A 2020-08-05 B 2020-08-01 B 2020-09-20 B 2020-12-31 C 2020-05-10 我的预期输出数据帧在列_1中的每个值应该只有一行,如果列_2中有多个日期用于列_1中的同一个键,则应选择下一个可用日期。如果只有一行,则应保留日期 预期产出: Column_1 Column_2 A

我有下面的Spark数据帧/数据集。列_2具有字符串格式的日期

Column_1 Column_2
A        2020-08-05
B        2020-08-01
B        2020-09-20
B        2020-12-31
C        2020-05-10

我的预期输出数据帧在列_1中的每个值应该只有一行,如果列_2中有多个日期用于列_1中的同一个键,则应选择下一个可用日期。如果只有一行,则应保留日期

预期产出:

Column_1 Column_2
A        2020-08-05
B        2020-09-20
C        2020-05-10

有没有办法实现这个Java火花?可能不使用UDF?

也许这是有帮助的-

dataset.show(false);
dataset.printSchema();
/**
*+--------+----------+
*|第1列|第2列|
* +--------+----------+
*| A | 2020-08-05|
*| D | 2020-08-01|
*| D | 2020-08-02|
*| B | 2020-08-01|
*| B | 2020-09-20|
*| B | 2020-12-31|
*| C | 2020-05-10|
* +--------+----------+
*
*根
*|--第_1列:字符串(nullable=true)
*|--第2列:字符串(可空=真)
*/
dataset.withColumn(“Column_2”),截止日期(col(“Column_2”))
.withColumn(“count”,count(“Column_2”)。超过(Window.partitionBy(“Column_1”))
当(列(“计数”).gt(1)时,带列(“正”),
当(col(“Column_2”).gt(current_date()),col(“Column_2”))
)。否则(列(“第2列”))
.withColumn(“负”),当(col(“count”).gt(1)时,
当(col(“Column_2”).lt(current_date()),col(“Column_2”))
)。否则(列(“第2列”))
.groupBy(“第1栏”)
.agg(最小(“正”).as(“正”)、最大(“负”).as(“负”))
.选择EXPR(“列_1”,“合并(正、负)为列_2”)
.显示(虚假);
/**
* +--------+----------+
*|第1列|第2列|
* +--------+----------+
*| A | 2020-08-05|
*| D | 2020-08-02|
*| B | 2020-09-20|
*| C | 2020-05-10|
* +--------+----------+
*/

首先创建数据帧

df_b = spark.createDataFrame([("A","2020-08-05"),("B","2020-08-01"),("B","2020-09-20"),("B","2020-12-31"),("C","2020-05-10")],[ "col1","col2"])
_w = W.partitionBy("col1").orderBy("col1")
df_b = df_b.withColumn("rn", F.row_number().over(_w))
这里的逻辑是,如果任何组的行数超过一行,则选择每个组的第二个元素。为了做到这一点,我们可以首先为每个组分配一个行号,我们将选择行数为1的每个组的第一个元素,以及每个组中行数大于1的每个组的前2行

case = F.expr("""
            CASE WHEN rn =1 THEN 1
                    WHEN rn =2 THEN 1
              END""")

df_b = df_b.withColumn('case_condition', case)
df_b = df_b.filter(F.col("case_condition") == F.lit("1")) 
中间输出

+----+----------+---+--------------+
|col1|      col2| rn|case_condition|
+----+----------+---+--------------+
|   B|2020-08-01|  1|             1|
|   B|2020-09-20|  2|             1|
|   C|2020-05-10|  1|             1|
|   A|2020-08-05|  1|             1|
+----+----------+---+--------------+
现在,最后只需取每组的最后一个元素--

df = df_b.groupBy("col1").agg(F.last("col2").alias("col2")).orderBy("col1")
df.show()
+----+----------+
|col1|      col2|
+----+----------+
|   A|2020-08-05|
|   B|2020-09-20|
|   C|2020-05-10|
+----+----------+

SCALA:这将给出结果

import org.apache.spark.sql.expressions.Window

val w = Window.partitionBy("Column_1")

df.withColumn("count", count("Column_2").over(w))
  .withColumn("later", expr("IF(Column_2 > date(current_timestamp), True, False)"))
  .filter("count = 1 or (count != 1 and later = True)")
  .groupBy("Column_1")
  .agg(min("Column_2").alias("Column_2"))
  .orderBy("Column_1")
  .show(false)

+--------+----------+
|Column_1|Column_2  |
+--------+----------+
|A       |2020-08-05|
|B       |2020-09-20|
|C       |2020-05-10|
+--------+----------+

它有一个例外,如果
列\u 1
的日期计数大于
1
,并且
当前时间戳之后没有日期,它将不会给出
列\u 1
值的结果“应选择下一个可用日期”这是什么逻辑?为什么选择第二个不是最后一个?比当前日期大的下一个即时日期。对于列_1中的B,今天是2020-08-04,当前日期后的下一个日期是2020-09-20。逻辑是它应该大于当前日期,并且当有两个以上的日期大于当前日期时,我们必须选择下一个可用的日期a,现在我明白了。我正在尝试通过汇总和收集列表来确定我们是否可以做到这一点?当第二行日期大于当前日期时,这一点就起作用了。假设第二行的日期小于当前日期,而第三行的日期大于当前日期,则将尝试此方法。。谢谢你能解释一下表达式(“结构(差异,列2)”)。。我可以理解,我们正在创建计数列,并在计数大于1时检查日期差。但我不明白其余部分,也不知道当一个键列的所有日期都小于当前日期时,这将如何工作,在这种情况下,是否有可能选择小于当前日期的最近日期?@Padfoot13288,更新了答案,现在,它将选择大于当前日期的最近日期,如果没有正值,则选择小于当前日期的最近日期。一个约会就是这样。我认为,新的解决方案是相当自我解释的