scala 每个单词的首字母大写|Spark斯卡拉

jhkqcmku  于 2022-12-18  发布在  Scala
关注(0)|答案(3)|浏览(305)

我有一个表如下-
| 识别号|城市|国家|
| - ------|- ------|- ------|
| 1个|美因河畔法兰克福|德国|
Dataframe 需要通过大写城市中每个单词的首字母来显示,即输出应如下所示-〉
| 识别号|城市|国家|
| - ------|- ------|- ------|
| 1个|美因河畔法兰克福|德国|
我使用的解决方案如下-〉
df.map(x => x.getString(1).trim().split(' ').map(_.capitalize).mkString(" ")).show()
这只提供别名为“value”的City列。
如何获得所有已实现上述转换的列?

w8f9ii69

w8f9ii691#

您可以使用initcap函数Docu
公共静态列initcap(列e)
通过将每个单词的第一个字母转换为大写来返回新的字符串列。单词用空格分隔。
比如“你好世界”会变成“你好世界”。
参数:e -(未记录)返回值:(无记录)自:1.5.0
样本代码

import org.apache.spark.sql.functions._

val data = Seq(("1", "Frankfurt am main", "Germany"))
val df = data.toDF("Id", "City", "Country")
df.withColumn("City", initcap(col("City"))).show

输出为:

+---+-----------------+-------+
| Id|             City|Country|
+---+-----------------+-------+
|  1|Frankfurt Am Main|Germany|
+---+-----------------+-------+

示例代码只返回1列,因为这正是您在map中编写的代码。取x(即df),从它的索引1中获取列,进行一些转换并返回。
您可以对map做任何您想做的事情,就像您在其他答案中看到的那样,但是map的输出需要包括所有列。
为什么在我的回答我不做Map?一般规则是:当内置SQL函数时,请使用它而不是自定义map/udf。大多数情况下,SQL函数在性能方面会更好,因为它更容易针对Catalyst进行优化

bfrts1fy

bfrts1fy2#

您可以调用udf并循环遍历所有列:

import spark.implicits._
val data = Seq(
  (1, "Frankfurt am main", "just test", "Germany"),
  (2, "should do this also", "test", "France"),
)
val df = spark.sparkContext.parallelize(data).toDF("ID", "City", "test", "Country")

val convertUDF = udf((value: String) => value.split(' ').map(_.capitalize).mkString(" "))
val dfCapitalized = df.columns.foldLeft(df) {
  (df, column) => df.withColumn(column, convertUDF(col(column)))
}
dfCapitalized.show(false)

+---+-------------------+---------+-------+
|ID |City               |test     |Country|
+---+-------------------+---------+-------+
|1  |Frankfurt Am Main  |Just Test|Germany|
|2  |Should Do This Also|Test     |France |
+---+-------------------+---------+-------+
7gs2gvoe

7gs2gvoe3#

您可以在Dataframe上执行map,然后简单地使用普通Scala函数进行大写。这为您提供了相当大的灵活性,使您可以使用Scala语言来进行具体的转换。
大概是这样的

import spark.implicits._
val df = Seq(
  (1, "Frankfurt am main", "Germany")
).toDF("ID", "City", "Country")

val output = df.map{
  row => (
    row.getInt(0),
    row.getString(1).split(' ').map(_.capitalize).mkString(" "),
    row.getString(2)
  )
}
output.show
+---+-----------------+-------+                                                                                                                                                                                                                                                 
| _1|               _2|     _3|                                                                                                                                                                                                                                                 
+---+-----------------+-------+                                                                                                                                                                                                                                                 
|  1|Frankfurt Am Main|Germany|                                                                                                                                                                                                                                                 
+---+-----------------+-------+

map函数内部,我们输出一个元组,其中的元素数量与您希望最终得到的列数量相同。
希望这有帮助!

相关问题