尝试将null替换Spark数据帧的特定列的值时遇到问题。我有一个数据框,其中有五十多个列,其中两个是关键列。我想创建一个具有相同架构的新数据框,并且新数据框应具有键列中的值和非键列中的空值。我尝试了以下方法,但遇到了问题:
//old_df is the existing Dataframe
val key_cols = List("id", "key_number")
val non_key_cols = old_df.columns.toList.filterNot(key_cols.contains(_))
val key_col_df = old_df.select(key_cols.head, key_cols.tail:_*)
val non_key_cols_df = old_df.select(non_key_cols.head, non_key_cols.tail:_*)
val list_cols = List.fill(non_key_cols_df.columns.size)("NULL")
val rdd_list_cols = spark.sparkContext.parallelize(Seq(list_cols)).map(l => Row(l:_*))
val list_df = spark.createDataFrame(rdd_list_cols, non_key_cols_df.schema)
val new_df = key_col_df.crossJoin(list_df)
当我在中仅包含字符串类型的列时,此方法很好old_df
。但是我有一些double类型和int类型的列,这会引发错误,因为rdd是空字符串的列表。
为了避免这种情况,我尝试将list_df
用作架构为的空数据框,non_key_cols_df
但结果crossJoin
是一个空数据框,我相信这是因为一个数据框为空。
我的要求是将non_key_cols
Null与作为单行数据框使用,以便我可以crossJoin
处理key_col_df
并形成所需的new_df
。
此外,将数据帧的关键列以外的所有列更新为null的任何其他更简便的方法也可以解决我的问题。提前致谢
crossJoin
这是一项昂贵的操作,因此,如果可能的话,您要避免这样做。一个更简单的解决方案是遍历所有非键列,并使用插入null lit(null)
。foldLeft
可以按以下方式使用它:
val keyCols = List("id", "key_number")
val nonKeyCols = df.columns.filterNot(keyCols.contains(_))
val df2 = nonKeyCols.foldLeft(df)((df, c) => df.withColumn(c, lit(null)))
输入示例:
+---+----------+---+----+
| id|key_number| c| d|
+---+----------+---+----+
| 1| 2| 3| 4.0|
| 5| 6| 7| 8.0|
| 9| 10| 11|12.0|
+---+----------+---+----+
会给:
+---+----------+----+----+
| id|key_number| c| d|
+---+----------+----+----+
| 1| 2|null|null|
| 5| 6|null|null|
| 9| 10|null|null|
+---+----------+----+----+
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句