应用于dataframe中空数组列的size函数在溢出后返回1
注意,在数据帧中的数组列上使用应用于dataframe中空数组列的size函数在溢出后返回1,dataframe,apache-spark,Dataframe,Apache Spark,注意,在数据帧中的数组列上使用size函数时,使用以下代码-其中包括split: import org.apache.spark.sql.functions.{trim, explode, split, size} val df1 = Seq( (1, "[{a},{b},{c}]"), (2, "[]"), (3, "[{d},{e},{f}]") ).toDF("col1", "col2&
size
函数时,使用以下代码-其中包括split
:
import org.apache.spark.sql.functions.{trim, explode, split, size}
val df1 = Seq(
(1, "[{a},{b},{c}]"),
(2, "[]"),
(3, "[{d},{e},{f}]")
).toDF("col1", "col2")
df1.show(false)
val df2 = df.withColumn("cola", split(trim($"col2", "[]"), ",")).withColumn("s", size($"cola"))
df2.show(false)
我们得到:
+----+-------------+---------------+---+
|col1|col2 |cola |s |
+----+-------------+---------------+---+
|1 |[{a},{b},{c}]|[{a}, {b}, {c}]|3 |
|2 |[] |[] |1 |
|3 |[{d},{e},{f}]|[{d}, {e}, {f}]|3 |
+----+-------------+---------------+---+
我希望为0,以便能够区分0或1个条目
这里有一些提示,那里也有一些提示,但没有任何帮助
如果我有以下条目:(2,null)
,那么我得到的大小是-1,我想这更有用
另一方面,这是从互联网上借来的样本:
val df = Seq("a" -> Array(1,2,3), "b" -> null, "c" -> Array(7,8,9)).toDF("id","numbers")
df.show
val df2 = df.withColumn("numbers", coalesce($"numbers", array()))
df2.show
val df3 = df2.withColumn("s", size($"numbers"))
df3.show()
返回0-如预期的那样
在这里寻找正确的方法,以便得到size=0
我认为根本原因是
split
返回一个空字符串,而不是null
scala> df1.withColumn("cola", split(trim($"col2", "[]"), ",")).withColumn("s", $"cola"(0)).select("s").collect()(1)(0)
res53: Any = ""
当然,包含空字符串的数组的大小是1
为了避免这种情况,也许你可以这样做
val df2 = df1.withColumn("cola", split(trim($"col2", "[]"), ","))
.withColumn("s", when(length($"cola"(0)) =!= 0, size($"cola"))
.otherwise(lit(0)))
df2.show(false)
+----+-------------+---------------+---+
|col1|col2 |cola |s |
+----+-------------+---------------+---+
|1 |[{a},{b},{c}]|[{a}, {b}, {c}]|3 |
|2 |[] |[] |0 |
|3 |[{d},{e},{f}]|[{d}, {e}, {f}]|3 |
+----+-------------+---------------+---+
此行为继承自,在Scala和Spark中以相同的方式使用。空输入是一种特殊情况,本文对此进行了详细讨论 Spark将
分割
功能的第二个参数(限制
)设置为-1。从Spark 3开始,我们现在可以传递函数的极限参数
您可以在Scala拆分函数与Spark SQL拆分函数中看到这一点:
“”.split(“”,“”)。长度
//res31:Int=1
sql(““”选择大小(拆分(“,”[,])”)“”)。显示
//+----------------------+
//|大小(拆分(,[,],-1))|
//+----------------------+
//| 1|
//+----------------------+
及
“,”.split(“,”).length//不设置limit=-1这将给出空数组
//res33:Int=0
“,”.split(“,”,-1).长度
//res34:Int=2
sql(““”选择大小(拆分(“,”,“[,]”))“”)。显示
//+-----------------------+
//|大小(拆分(、[、]、-1))|
//+-----------------------+
//| 2|
//+-----------------------+
好吧,假设?我认为这是一个公平的观察。同意吗?是的,我认为如果你从任何非null的东西开始,字符串操作永远不会返回null。我在80年代在uni用pascal研究了字符串包,结果可能是null。这是经典的东西!;)虽然我不认为这是一个好的实现,但我还是要寻找答案。