我有一个简单的数据框,其中包含一些字符串cloumns:
Name age address
micheal 21 Washington
Jhon 10 San Franciso
我希望在每个字符串类型列中添加撇号,我需要检查 列类型并相应地更改它,结果将是:
Name age address
'micheal' 21 'Washington'
'Jhon' 20 'San Francisco'
我没有多少列,所以我需要动态查询列类型。
答案 0 :(得分:1)
然后有两个要求:
我希望将撇号添加到每个字符串类型列
我不会有多少列
// load the dataset from a CSV file
val names = spark.
read.
option("header", true).
option("inferSchema", true).
csv("names.txt")
scala> names.show
+-------+---+------------+
| Name|age| address|
+-------+---+------------+
|micheal| 21| Washington|
| Jhon| 10|San Franciso|
+-------+---+------------+
对于这种特殊情况,架构如下:
scala> names.printSchema
root
|-- Name: string (nullable = true)
|-- age: integer (nullable = true)
|-- address: string (nullable = true)
我们有两个字符串类型的字段,但是要求我们不知道我们将拥有多少列并不重要。
用于Scala的Spark SQL的DataFrame API实际上可以帮助行Dataset[Row]
类型的行。
import org.apache.spark.sql.Row
scala> names.collect.head.isInstanceOf[Row]
res0: Boolean = true
来自org.apache.spark.sql.Row's scaladoc:
表示关系运算符的一行输出。允许通过序数进行通用访问,这将导致原语的装箱开销,以及本机原语访问。
尽管如此,解决方案可能如下:
import org.apache.spark.sql.DataFrame
def quoteStringColumns(df: DataFrame) = {
import org.apache.spark.sql.types.{StringType, StructType}
def stringFieldNames(schema: StructType) = {
schema.filter(_.dataType == StringType).map(_.name)
}
val columns = stringFieldNames(names.schema)
val quoteUDF = udf { s: String => s"'$s'" }
columns.foldLeft(df) { case (resultDF, c) => resultDF.withColumn(c, quoteUDF(col(c))) }
}
val r = quoteStringColumns(names)
scala> r.show
+---------+---+--------------+
| Name|age| address|
+---------+---+--------------+
|'micheal'| 21| 'Washington'|
| 'Jhon'| 10|'San Franciso'|
+---------+---+--------------+
答案 1 :(得分:1)
快速而简单的解决方案是map
超过dtypes
和select
:
import org.apache.spark.sql.functions.{col, concat, lit}
val exprs = df.dtypes.map {
// if column is a string concat with quotes and alias
case (c, "StringType") => concat(lit("'"), col(c), lit("'")).alias(c)
// otherwise keep as is.
case (c, _) => col(c)
}
df.select(exprs: _*).show
+---------+---+---------------+
| Name|age| address|
+---------+---+---------------+
|'michael'| 21| 'Washington'|
| 'Jhon'| 20|'San Francisco'|
+---------+---+---------------+