在 Spark 数据框中过滤多列的最佳方法是啥?

Posted

技术标签:

【中文标题】在 Spark 数据框中过滤多列的最佳方法是啥?【英文标题】:What is the best way to filter many columns together in Spark dataframe?在 Spark 数据框中过滤多列的最佳方法是什么? 【发布时间】:2020-01-16 07:47:03 【问题描述】:

样本数据:

+--------------------+-----+--------+----+----------+--------+-----------+
|                  id|click|    hour|  C1|banner_pos| site_id|site_domain|
+--------------------+-----+--------+----+----------+--------+-----------+
| NULL               |    0|14102100|1005|         0|1fbe01fe|   f3845767|
|10000169349117863715|    0|14102100|1005|         0|1fbe01fe|   f3845767|
|10000371904215119486|    0|NULL    |1005|         0|1fbe01fe|   f3845767|
|10000640724480838376|    0|14102100|1005|         0|1fbe01fe|   f3845767|
|10000679056417042096|    0|14102100|1005|         1|fe8cc448|   9166c161|
+--------------------+-----+--------+----+----------+--------+-----------+

预期结果:

+--------------------+-----+--------+----+----------+--------+-----------+
|                  id|click|    hour|  C1|banner_pos| site_id|site_domain|
+--------------------+-----+--------+----+----------+--------+-----------+
| NULL               |    0|14102100|1005|         0|1fbe01fe|   f3845767|
|10000371904215119486|    0|NULL    |1005|         0|1fbe01fe|   f3845767|
+--------------------+-----+--------+----+----------+--------+-----------+

我想过滤数据框中的所有列,条件是至少一列包含“NULL”字符串。我有很多专栏,大约 30 个。 我已经看到可以添加一些列条件,例如this:

df2 = df1.filter($"Status" === 2 || $"Status" === 3)

但是由于我有许多列具有相同的条件,有没有办法将columns 视为一个集合并将它们一起过滤? 我尝试了以下方法,但似乎不起作用:

  df2.filter(
    lit(
      df2.columns.map(col(_).contains("NULL")).contains(lit(true))
    )
  ).show()

似乎df2.columns.map(col(_).contains("NULL")).contains(lit(true)) 总是返回false

为什么会这样?你能解释一下为什么这不起作用吗?


以下代码可用于上述目的。

  df.filter(
    lit(true).isin(df.columns.map(col(_).contains("NULL")): _*)
  ).show()

【问题讨论】:

提供样本数据集和所需输出会非常有帮助 【参考方案1】:

原因是你的第一个sn-p

df.columns.map(col(_).contains("NULL"))

返回一个

Array[Column]

然后您尝试使用此语句传递整个数组以搜索布尔文字“true”

df2.columns.map(col(_).contains("NULL")).contains(lit(true))

因为它是Array[Column] 的复杂结构,所以它不起作用。

但是下面这个表达式:

df.columns.map(col(_).contains("NULL")): _*

将每个数组元素作为一个单独的参数发送给isin 函数,这样您的过滤器就可以工作了。

希望这可以解释!

【讨论】:

【参考方案2】:
df.filter(r=> r.toSeq.exists(c => c == null))

【讨论】:

解释这段代码为什么有效以及它实际做了什么。

以上是关于在 Spark 数据框中过滤多列的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Spark数据框中多列计算的优化方式?

在单个 spark 数据框中减去两个字符串列的最佳 PySpark 实践是啥?

如何在 pyspark 中对 spark 数据框中的多列求和?

如何在 pyspark 中对 spark 数据框中的多列求和?

将多列映射到 Spark 数据框中的单个键

基于在 DataBrick 中的笔记本顶部提取小部件值来动态检索/过滤 Spark 框架的最佳 PySpark 实践是啥?