我需要将 RDBMS 表摄取到 Hive 中,并且在使用 regex_replace 模式将其插入 Hive 表之前,我必须清理其 String 列中的数据。在无法理解如何将它应用于我的 dataFrame 之后,我终于在 Scala 中遇到了一个方法,它是 foldLeft
,它有助于满足要求。
我了解 foldLeft 如何处理集合,例如:
List(1,3,9).foldLeft(100)((x,y) => x+y)
foldLeft 接受参数:initialValue 和一个函数。它将函数的结果添加到累加器中。在上述情况下,结果为:113。
但是当涉及到数据框时,我无法理解它是如何工作的。
val stringColumns = yearDF.schema.fields.filter(_.dataType == StringType).map(_.name)
val finalDF = stringColumns.foldLeft(yearDF){ (tempdf, colName) => tempdf.withColumn(colName, regexp_replace(col(colName), "\n", "")) }
在上面的代码中,我从 dataFrame:
yearDF
获得了 String 列,它保存在 foldLeft
的累加器中。我对 foldLeft
中使用的函数有以下疑问:withColumns
并将结果添加到yearDF,为什么在
谁能解释一下,以便我可以更好地了解foldLeft。
最佳答案
考虑一个与您的 DataFrame 版本更相似的简单 foldLeft
示例:
List(3, 2, 1).foldLeft("abcde")((acc, x) => acc.take(x))
如果仔细观察
(acc, x) => acc.take(x)
函数在每次迭代中的作用,foldLeft
与以下内容没有区别:"abcde".take(3).take(2).take(1)
// Result: "a"
回到 DataFrame 的
foldLeft
:stringColumns.foldLeft(yearDF){ (tempdf, colName) =>
tempdf.withColumn(colName, regexp_replace(col(colName), "\n", ""))
}
同样,它与以下内容没有区别:
val sz = stringColumns.size
yearDF.
withColumn(stringColumns(0), regexp_replace(col(stringColumns(0)), "\n", "")).
withColumn(stringColumns(1), regexp_replace(col(stringColumns(1)), "\n", "")).
...
withColumn(stringColumns(sz - 1), regexp_replace(col(stringColumns(sz - 1)), "\n", ""))
在每次迭代 (i = 0, 1, 2, ...) 中,
tempDF
保存了一个新的 DataFrame,它是通过应用 withColumn(stringColumns(i), ...)
转换而来的,从 yearDF
开始从
withColumn(stringColumns(i), regexp_replace(col(stringColumns(i)), "\n", ""))
,方法 withColumn
创建一个新的 DataFrame,“添加”一个与它派生的 stringColumns(i)
列同名的列,从而基本上产生一个新的 DataFrame,其列列表与原始 yearDF
相同。关于scala - Scala 中的 foldLeft 如何在 DataFrame 上工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52025223/