【问题标题】:Filter a dataframe using a list of tuples in spark scala使用 spark scala 中的元组列表过滤数据框
【发布时间】:2019-09-26 14:43:00
【问题描述】:

我试图通过将其两列(在本例中为主题和流)与元组列表进行比较来过滤 scala 中的数据框。如果列值和元组值相等,则过滤行。

val df = Seq(
  (0, "Mark", "Maths", "Science"),
  (1, "Tyson", "History", "Commerce"),
  (2, "Gerald", "Maths", "Science"),
  (3, "Katie", "Maths", "Commerce"),
  (4, "Linda", "History", "Science")).toDF("id", "name", "subject", "stream")

示例输入:

+---+------+-------+--------+
| id|  name|subject|  stream|
+---+------+-------+--------+
|  0|  Mark|  Maths| Science|
|  1| Tyson|History|Commerce|
|  2|Gerald|  Maths| Science|
|  3| Katie|  Maths|Commerce|
|  4| Linda|History| Science|
+---+------+-------+--------+

需要过滤上述df的元组列表

  val listOfTuples = List[(String, String)] (
    ("Maths" , "Science"),
    ("History" , "Commerce")
)

预期结果:

+---+------+-------+--------+
| id|  name|subject|  stream|
+---+------+-------+--------+
|  0|  Mark|  Maths| Science|
|  1| Tyson|History|Commerce|
|  2|Gerald|  Maths| Science|
+---+------+-------+--------+

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    您可以使用带有结构的isin 来实现(需要 spark 2.2+):

    val df_filtered = df
        .where(struct($"subject",$"stream").isin(listOfTuples.map(typedLit(_)):_*))
    

    或者用leftsemi加入:

    val df_filtered = df
    .join(listOfTuples.toDF("subject","stream"),Seq("subject","stream"),"leftsemi")
    

    【讨论】:

    • 不错的解决方案。根据 Spark API 文档,isin 从 Spark1.5+ 起应该可用。
    • @Leo C 是的,但 typedLit 自 spark 2.2 起可用
    【解决方案2】:

    你可以简单地filter

    val resultDF = df.filter(row => {
      List(
        ("Maths", "Science"),
        ("History", "Commerce")
      ).contains(
        (row.getAs[String]("subject"), row.getAs[String]("stream")))
    })
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 2011-05-27
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 2021-01-30
      相关资源
      最近更新 更多