Spark Dataframe用Null替换一行中特定列的值

RSG

尝试将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_colsNull作为单行数据框使用,以便我可以crossJoin处理key_col_df并形成所需的new_df

此外,将数据帧的关键列以外的所有列更新为null的任何其他更简便的方法也可以解决我的问题。提前致谢

ido堂

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章