如何将数据框的几列与其其他列进行比较
Posted
技术标签:
【中文标题】如何将数据框的几列与其其他列进行比较【英文标题】:How to compare few columns of a dataframe with its other columns 【发布时间】:2019-05-05 19:27:14 【问题描述】:我在 spark 的数据框中有 8 列,
-
名字_a,
status_a,
date_a,
ID_a,
姓名_b,
status_b,
date_b,
ID_b.
现在我想将前四列与后四列进行比较,即Name_a
与Name_b
、status_a
与status_b
等。我如何使用scala
语言在spark 中做到这一点?
【问题讨论】:
欢迎来到 Stack Overflow!请查看writing the perfect question 以帮助您提出一个好问题,从而获得一个好的答案。 【参考方案1】:问题:我想将前四列与后四列进行比较 Name_a 和 Name_b、status_a 和 status_b 等列。如何 我可以用 scala 语言在 spark 中做到这一点吗?
选项 1:
以下是使用except
执行此操作的方法,您可以实现此目的...
except
,您可以找到如下所示的差异,这是不言自明的......
package com.examples
import org.apache.log4j.Level, Logger
import org.apache.spark.internal.Logging
import org.apache.spark.sql.SparkSession
/**
* @author : Ram Ghadiyaram
*/
object FindDataFrameColumnDifferences extends App with Logging
Logger.getLogger("org").setLevel(Level.WARN)
case class Employee(Name_a: String, status_a: Int, date_a: String, ID_a: Int
, Name_b: String, status_b: Int, date_b: String, ID_b: Int)
val spark: SparkSession = SparkSession.builder().appName(this.getClass.getName).master("local[*]").getOrCreate()
//spark.sparkContext.setLogLevel("ERROR")
import spark.implicits._
val df = List(
Employee("Ram", 1, "21-Mar-2019", 20048965, "Ram", 1, "21-Mar-2019", 20048965),
Employee("Ram", 1, "21-Mar-2019", 20048965, "Ram", 1, "21-Mar-2019", 20048965),
Employee("Mishy_tics", 1, "21-Mar-2019", 20048965, "Mishy", 1, "21-Mar-2019", 20048965),
Employee("Mishy_tics", 1, "21-Mar-2019", 20048965, "tics", 1, "21-Mar-2019", 20048965)
).toDF
logInfo("original dataframe with 8 columns")
df.show(false)
logInfo("Now take first 4 columns in the original dataframe and rename using alias ")
val firstDataFrame = df.selectExpr("Name_a as name", "status_a as status", "date_a as date", "ID_a as id")
logInfo("printing first dataframe ")
firstDataFrame.show
logInfo("Now take last 4 columns in the original dataframe and rename using alias ")
val secondDataFrame = df.selectExpr("Name_b as name", "status_b as status", "date_b as date", "ID_b as id")
logInfo("printing second dataframe ")
secondDataFrame.show
val columns = firstDataFrame.schema.fields.map(_.name)
logInfo("first except second")
var selectiveDifferences = columns.map(col => firstDataFrame.select(col).except(secondDataFrame.select(col)))
// columns contains different values.
selectiveDifferences.map(diff =>
if (diff.count > 0) diff.show
)
selectiveDifferences = columns.map(col => secondDataFrame.select(col).except(firstDataFrame.select(col)))
logInfo("second except first")
// columns contains different values.
selectiveDifferences.map(diff =>
if (diff.count > 0) diff.show
)
2019-05-05 19:10:05 WARN NativeCodeLoader:62 - 无法为您的平台加载 native-hadoop 库...在适用的情况下使用内置 java 类
2019-05-05 19:10:13 INFO FindDataFrameColumnDifferences:54 - 8 列的原始数据框
+---------+--------+------------+--------+------+- --------+-----------+--------+
|Name_a |status_a|date_a |ID_a |Name_b|status_b|date_b |ID_b |
+---------+--------+------------+--------+------+- --------+-----------+--------+
|内存 |1 |2019 年 3 月 21 日|20048965|内存 |1 |2019 年 3 月 21 日|20048965|
|内存 |1 |2019 年 3 月 21 日|20048965|内存 |1 |2019 年 3 月 21 日|20048965|
|Mishy_tics|1 |2019 年 3 月 21 日|20048965|Mishy |1 |2019 年 3 月 21 日|20048965|
|Mishy_tics|1 |2019 年 3 月 21 日|20048965|tics |1 |2019 年 3 月 21 日|20048965|
+---------+--------+------------+--------+------+- --------+-----------+--------+
2019-05-05 19:10:13 INFO FindDataFrameColumnDifferences:54 - 现在在原始数据框中取前 4 列并使用别名重命名
2019-05-05 19:10:14 INFO FindDataFrameColumnDifferences:54 - 打印第一个数据帧
+---------+------+------------+--------+
|名称|状态|日期|编号|
+---------+------+------------+--------+
|公羊| 1|2019 年 3 月 21 日|20048965|
|公羊| 1|2019 年 3 月 21 日|20048965|
|Mishy_tics| 1|2019 年 3 月 21 日|20048965|
|Mishy_tics| 1|2019 年 3 月 21 日|20048965|
+---------+------+------------+--------+
2019-05-05 19:10:14 INFO FindDataFrameColumnDifferences:54 - 现在取原始数据框中的最后 4 列并使用别名重命名
2019-05-05 19:10:14 INFO FindDataFrameColumnDifferences:54 - 打印第二个数据帧
+-----+------+------------+--------+
|名称|状态|日期|编号|
+-----+------+------------+--------+
|公羊| 1|2019 年 3 月 21 日|20048965|
|公羊| 1|2019 年 3 月 21 日|20048965|
|迷糊| 1|2019 年 3 月 21 日|20048965|
|抽动| 1|2019 年 3 月 21 日|20048965|
+-----+------+------------+--------+
2019-05-05 19:10:14 信息 FindDataFrameColumnDifferences:54 - 除了第二个
+----------+
|姓名|
+----------+
|Mishy_tics|
+----------+
2019-05-05 19:10:29 INFO FindDataFrameColumnDifferences:54 - 第二个,除了第一个
+-----+
|姓名|
+-----+
|迷糊|
|抽动|
+-----+
选项 2: - 另一种方法是在使用equi join/self join on name 和状态创建第一个包含 8 列的数据框之后......您可以找到它们之间的差异。
见:Joining Spark dataframes on the key
选项 2 是我觉得最简单的方式..
【讨论】:
Mishy 你试过这个吗? ,如果您还可以,请注意以所有者的身份接受答案并投票 其实我正在尝试做一个CDC进程,所以我想要Name_a,Status_a与Name_b,Status_b之间的区别。我也想同时捕获更新,而不是多个步骤 虽然我无法猜测你在做什么,但分成 2 个数据框使用第二种连接方法来找出差异......请正确地提出问题,并且格式非常重要从用户那里得到答案。其他人应该能够理解您的问题..请参阅如何格式化问题的帮助。并提供您想要实现的代码 sn-p .... 并且无法做到。否则将被视为低质量问题..【参考方案2】:假设一条记录可以表示为:
Person(name: String, status: Boolean, date: String, id: Int)
在您的情况下,每一行都包含Person
s 的双重记录。您可以将两个人排成一行,如下所示:
case class Person(name: String, status: Boolean, date: String, id: Int)
case class TuplePerson(a: Person, b: Person)
然后你可以使用数据集来比较a with b
。完整代码如下:
case class Person(name: String, status: Boolean, date: String, id: Int)
case class TuplePerson(a: Person, b: Person)
val df = Seq(
(TuplePerson(Person("John", true,"15-05-2019", 54), Person("John", true,"15-05-2019", 54))),
(TuplePerson(Person("Sofia", true,"15-05-2019", 54),Person("John", true,"15-05-2019", 53))),
(TuplePerson(Person("John", true,"15-05-2019", 52), Person("John", true,"15-05-2019", 52))))
.toDS()
df.where($"a" === $"b").show(false)
输出:
+----------------------------+----------------------------+
|a |b |
+----------------------------+----------------------------+
|[John, true, 15-05-2019, 54]|[John, true, 15-05-2019, 54]|
|[John, true, 15-05-2019, 52]|[John, true, 15-05-2019, 52]|
+----------------------------+----------------------------+
或者获取左右部分的差:
df.where($"a" =!= $"b").show(false)
+-----------------------------+----------------------------+
|a |b |
+-----------------------------+----------------------------+
|[Sofia, true, 15-05-2019, 54]|[John, true, 15-05-2019, 53]|
+-----------------------------+----------------------------+
【讨论】:
嗨,Mishy,这是您要寻找的差异还是您的意思?以上是关于如何将数据框的几列与其其他列进行比较的主要内容,如果未能解决你的问题,请参考以下文章