比较两个数据框中列的值

Posted

技术标签:

【中文标题】比较两个数据框中列的值【英文标题】:Comparing the value of columns in two dataframe 【发布时间】:2018-09-13 06:18:12 【问题描述】:

我有两个数据框,一个具有唯一值 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]

我的目标是将第二个数据帧与第一个数据帧进行比较并更新第一个数据帧中的值,前提是 df2 的特定 iddt 的值大于 df1 中的值,并且如果它满足大于条件,然后比较其他字段。

【问题讨论】:

【参考方案1】:

您需要将两个数据框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) 或使用窗口函数,因为diffDf 数据帧中的每个id 应该只有最后一行。可以这样做(这里的例子会选择速度最大的行,但要根据实际需要而定):

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)?。


要在df1 数据框中用相同的id 替换旧行,请将数据框与外部连接和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 首先尝试从 diffDf (b) 数据帧中获取值。如果该值为 null,它将采用来自 df1 (a) 的值。

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

+---------------+-------------------+-----+-----------------+
|             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]|
+---------------+-------------------+-----+-----------------+

【讨论】:

先生,如果我们有大量数据(比如说流数据),这种方法会有效吗,因为加入有时会吓到我。 @experiment:如果您想比较两个数据框,您仍然需要进行连接。但是,如果其中一个数据帧非常小,则可以将其收集到驱动程序并按原样使用,但您将失去使用 Spark 的优势。

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

将定义集中的值设置为 Pandas 数据框中列的给定值(f.e. NaN)

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

pyspark:比较给定列的值时从数据框中获取公共数据

给定列名,数据框中列的平均值

如何更改pyspark数据框中列的顺序?

数据框中列的匹配值