简单的请求是我需要帮助将列添加到数据框中,但是该列必须为空,其类型来自... spark.sql.types,类型必须为用字符串定义。
我可以使用IFS或案例来做到这一点,但我正在寻找更优雅的东西。不需要为org.apache.spark.sql.types
中的每种类型编写案例的东西例如,如果我这样做:
df = df.withColumn("col_name", lit(null).cast(org.apache.spark.sql.types.StringType))
它按预期工作,但我的类型存储为字符串,
var the_type = "StringType"
或 var the_type =" org.apache.spark.sql.types.stringtype"
,我无法通过定义字符串的类型来使它起作用。
对于那些感兴趣的人,还有一些更多详细信息:我有一个包含元组的集合(col_name,col_type)作为字符串,我需要添加具有正确类型的列,以在2个dataframes之间进行未来的联合。
。我目前有一个:
for (i <- set_of_col_type_tuples) yield {
val tip = Class.forName("org.apache.spark.sql.types."+i._2)
df = df.withColumn(i._1, lit(null).cast(the_type))
df }
如果我使用
val the_type = Class.forName("org.apache.spark.sql.types."+i._2)
我得到
error: overloaded method value cast with alternatives: (to: String)org.apache.spark.sql.Column <and> (to: org.apache.spark.sql.types.DataType)org.apache.spark.sql.Column cannot be applied to (Class[?0])
如果我使用
val the_type = Class.forName("org.apache.spark.sql.types."+i._2).getName()
这是一个字符串,所以我得到:
org.apache.spark.sql.catalyst.parser.ParseException: mismatched input '.' expecting {<EOF>, '('}(line 1, pos 3)
== SQL == org.apache.spark.sql.types.StringType
---^^^
编辑:因此,要清楚,该集合包含类似的元素(" col1"," integertype"),(" col2"," stringtype")不(" col1"," int"),("col2"," string")。简单的演员(i._2)不起作用。
谢谢。
您可以使用过载的方法cast
,该方法的字符串作为参数:
val stringType : String = ...
column.cast(stringType)
def cast(to:string):列
使用规范字符串将列施加到其他数据类型 类型的表示。
您还可以扫描所有数据类型:
val types = classOf[DataTypes]
.getDeclaredFields()
.filter(f => java.lang.reflect.Modifier.isStatic(f.getModifiers()))
.map(f => f.get(new DataTypes()).asInstanceOf[DataType])
现在类型是数组[DataType]。您可以将其翻译成映射:
val typeMap = types.map(t => (t.getClass.getSimpleName.replace("$", ""), t)).toMap
并在代码中使用:
column.cast(typeMap(yourType))