Как сравнить несколько столбцов информационного кадра с другими его столбцами - PullRequest
1 голос
/ 05 мая 2019

У меня есть 8 столбцов в кадре данных в искре,

  1. Name_a,
  2. status_a,
  3. date_a,
  4. ID_a,
  5. Name_b,
  6. status_b,
  7. date_b,
  8. ID_b.

Теперь я хочу сравнить первые четыре столбца споследние 4 столбца, которые Name_a с Name_b, status_a с status_b и т. д. Как я могу сделать это в искре с scala язык?

Ответы [ 2 ]

2 голосов
/ 06 мая 2019

Вопрос: я хочу сравнить первые четыре столбца с последними 4 столбцы, которые являются Name_a с Name_b, status_a с status_b и т. д. Как могу ли я сделать это в искре с языком скала.

Вариант 1: Ниже описан способ сделать это, используя except, вы можете достичь этого ...

  • Взять все 8 столбцов в качестве кадра данных
  • взять первые 4 столбца в фрейме данных и присвоить ему псевдоним ... это ваш первый фрейм данных
  • взять последние 4 столбца кадра данных и присвоить ему псевдоним с тем же именем, что и в первом кадре данных ... который станет вашим вторым кадром данных
  • с помощью 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 - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
2019-05-05 19:10:13 INFO  FindDataFrameColumnDifferences:54 - original dataframe with 8 columns
+----------+--------+-----------+--------+------+--------+-----------+--------+
|Name_a    |status_a|date_a     |ID_a    |Name_b|status_b|date_b     |ID_b    |
+----------+--------+-----------+--------+------+--------+-----------+--------+
|Ram       |1       |21-Mar-2019|20048965|Ram   |1       |21-Mar-2019|20048965|
|Ram       |1       |21-Mar-2019|20048965|Ram   |1       |21-Mar-2019|20048965|
|Mishy_tics|1       |21-Mar-2019|20048965|Mishy |1       |21-Mar-2019|20048965|
|Mishy_tics|1       |21-Mar-2019|20048965|tics  |1       |21-Mar-2019|20048965|
+----------+--------+-----------+--------+------+--------+-----------+--------+

2019-05-05 19:10:13 INFO  FindDataFrameColumnDifferences:54 - Now take first 4 columns in the original dataframe and rename using alias 
2019-05-05 19:10:14 INFO  FindDataFrameColumnDifferences:54 - printing first dataframe 
+----------+------+-----------+--------+
|      name|status|       date|      id|
+----------+------+-----------+--------+
|       Ram|     1|21-Mar-2019|20048965|
|       Ram|     1|21-Mar-2019|20048965|
|Mishy_tics|     1|21-Mar-2019|20048965|
|Mishy_tics|     1|21-Mar-2019|20048965|
+----------+------+-----------+--------+

2019-05-05 19:10:14 INFO  FindDataFrameColumnDifferences:54 - Now take last 4 columns in the original dataframe and rename using alias 
2019-05-05 19:10:14 INFO  FindDataFrameColumnDifferences:54 - printing second dataframe 
+-----+------+-----------+--------+
| name|status|       date|      id|
+-----+------+-----------+--------+
|  Ram|     1|21-Mar-2019|20048965|
|  Ram|     1|21-Mar-2019|20048965|
|Mishy|     1|21-Mar-2019|20048965|
| tics|     1|21-Mar-2019|20048965|
+-----+------+-----------+--------+

2019-05-05 19:10:14 INFO  FindDataFrameColumnDifferences:54 - first except second
+----------+
|      name|
+----------+
|Mishy_tics|
+----------+

2019-05-05 19:10:29 INFO  FindDataFrameColumnDifferences:54 - second except first
+-----+
| name|
+-----+
|Mishy|
| tics|
+-----+

Вариант 2: - Другой способ - после создания первого кадра данных с 8 столбцами, используя equi join / self join для имени и статуса ... вы можете найти различия между ними.

См .: Присоединение к кадрам данных Spark на ключе

Вариант 2 - самый простой способ, которым я себя чувствую ..

1 голос
/ 07 мая 2019

Предполагая, что одна запись может быть представлена ​​как:

Person(name: String, status: Boolean, date: String, id: Int)

В вашем случае каждая строка содержит двойную запись Person с.Вы можете заключить двух человек в один ряд следующим образом:

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]|
+-----------------------------+----------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...