比较两个数据帧中列的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比较两个数据帧中列的值相关的知识,希望对你有一定的参考价值。

我有两个数据帧,一个具有id的唯一值,而另一个可以具有不同id的多个值。

这是数据帧df1

id | dt| speed | stats
358899055773504 2018-07-31 18:38:34 0 [9,-1,-1,13,0,1,0]
358899055773505 2018-07-31 18:48:23 4 [8,-1,0,22,1,1,1]

df2

id | dt| speed | stats
358899055773504 2018-07-31 18:38:34 0 [9,-1,-1,13,0,1,0]
358899055773505 2018-07-31 18:54:23 4 [9,0,0,22,1,1,1]
358899055773504 2018-07-31 18:58:34 0 [9,0,-1,22,0,1,0]
358899055773504 2018-07-31 18:28:34 0 [9,0,-1,22,0,1,0]
358899055773505 2018-07-31 18:38:23 4 [8,-1,0,22,1,1,1]

我的目的是比较第二个数据帧和第一个数据帧并更新第一个数据帧中的值,只有当dt的特定iddf2值大于df1中的值时,如果它满足大于条件然后比较其他字段同样。

答案

您需要将两个数据帧一起join进行任何比较。

您可以做的是首先加入数据框,然后执行所有过滤以获取包含应更新的所有行的新数据框:

val diffDf = df1.as("a").join(df2.as("b"), Seq("id"))
  .filter($"b.dt" > $"a.dt")
  .filter(...)                                          // Any other filter required
  .select($"id", $"b.dt", $"b.speed", $"b.stats")

注意:在某些情况下,需要执行groupBy(id)或使用窗口函数,因为id数据帧中每个diffDf应该只有一个最后一行。这可以按如下方式完成(此处的示例将选择速度最大的行,但这取决于实际要求):

val w = Window.partitionBy($"id").orderBy($"speed".desc)
val diffDf2 = diffDf.withColumn("rn", row_number.over(w)).where($"rn" === 1).drop("rn")

有关不同方法的更多深入信息可以在这里看到:How to max value and keep all columns (for max records per group)?


要在id数据帧中使用相同的df1替换旧行,请将数据帧与外部联接和coalesce组合:

val df = df1.as("a").join(diffDf.as("b"), Seq("id"), "outer")
  .select(
    $"id", 
    coalesce($"b.dt", $"a.dt").as("dt"), 
    coalesce($"b.speed", $"a.speed").as("speed"), 
    coalesce($"b.stats", $"a.stats").as("stats")
  )

coalesce首先尝试从diffDfb)数据框中获取值。如果该值为null,则将采用df1a)中的值。

仅使用提供的示例输入数据帧的时间过滤器时的结果:

+---------------+-------------------+-----+-----------------+
|             id|                 dt|speed|            stats|
+---------------+-------------------+-----+-----------------+
|358899055773504|2018-07-31 18:58:34|    0|[9,0,-1,22,0,1,0]|
|358899055773505|2018-07-31 18:54:23|    4| [9,0,0,22,1,1,1]|
+---------------+-------------------+-----+-----------------+

以上是关于比较两个数据帧中列的值的主要内容,如果未能解决你的问题,请参考以下文章

如何用python中其他数据帧中的条目替换一个数据帧中列的丢失条目?

计算两个连续日期之间的唯一 ID,它们是 PySpark 中列的值

如何将sqlalchemy中列的默认值设置为关系中列的值?

如何选择数据框中列的前 3 个值 - 熊猫

如果 pyspark 数据帧的行基于两列的值位于另一个数据帧中,如何删除它们?

SQL Server 表未显示表中列的值