我想删除所有重复条目的记录,但是说时间戳的差异可以是任何时间量的偏移量,但为了简单起见将使用2分钟。
+-------------------+-----+----+
|Date |ColA |ColB|
+-------------------+-----+----+
|2017-07-04 18:50:21|ABC |DEF |
|2017-07-04 18:50:26|ABC |DEF |
|2017-07-04 18:50:21|ABC |KLM |
+-------------------+-----+----+
我希望我的数据框只有行
+-------------------+-----+----+
|Date |ColA |ColB|
+-------------------+-----+----+
|2017-07-04 18:50:26|ABC |DEF |
|2017-07-04 18:50:21|ABC |KLM |
+-------------------+-----+----+
我尝试过类似的东西,但这并没有删除重复项。
val joinedDfNoDuplicates = joinedDFTransformed.as("df1").join(joinedDFTransformed.as("df2"), col("df1.ColA") === col("df2.ColA") &&
col("df1.ColB") === col("df2.ColB") &&
&& abs(unix_timestamp(col("Date")) - unix_timestamp(col("Date"))) > offset
)
现在,我只是根据某些列在数据上选择不同或分组Find minimum for a timestamp through Spark groupBy dataframe,但我想要一个更强大的解决方案,其原因是该间隔之外的数据可能是有效数据。此外,根据要求,偏移量可能会在5s或5分钟内改变。
有人向我提到过创建一个比较日期的UDF,以及所有其他列是否相同,但我不确定如何做到这一点,我要么过滤掉行或添加一个标志,然后删除那些行任何帮助非常感谢。
这里有类似的SQL问题Duplicate entries with different timestamp
谢谢!
答案 0 :(得分:5)
我会这样做:
守则可以是以下内容:
import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions._
val w = Window.partitionBy("dummy").orderBy("Date") // step 1
df.withColumn("dummy", lit(1)) // this is step 1
.withColumn("previousDate", lag($"Date", 1) over w) // step 2
.withColumn("difference", unix_timestamp($"Date") - unix_timestamp("previousDate")) // step 3
如果您有可能在时间上接近的记录对,则上述解决方案有效。如果您有两个以上的记录,则可以将每个记录与窗口中的第一个记录(而不是前一个记录)进行比较,因此不使用lag($"Date",1)
,而是使用first($"Date")
。在这种情况下,差异'列包含当前记录与窗口中第一条记录之间的时间差。