Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将列转换为存储在字符串中的sql类型_Scala_Apache Spark_Apache Spark Sql_Spark Dataframe - Fatal编程技术网

Scala 将列转换为存储在字符串中的sql类型

Scala 将列转换为存储在字符串中的sql类型,scala,apache-spark,apache-spark-sql,spark-dataframe,Scala,Apache Spark,Apache Spark Sql,Spark Dataframe,简单的请求是我需要帮助将列添加到数据帧,但是,列必须为空,其类型来自…spark.sql.types,并且必须从字符串定义类型 我可能可以用ifs或case来做,但我正在寻找更优雅的东西。它不需要为org.apache.spark.sql.types中的每种类型编写案例 例如,如果我这样做: df = df.withColumn("col_name", lit(null).cast(org.apache.spark.sql.types.StringType)) 它按预期工作,但我将类型存储为字

简单的请求是我需要帮助将列添加到数据帧,但是,列必须为空,其类型来自…spark.sql.types,并且必须从字符串定义类型

我可能可以用ifs或case来做,但我正在寻找更优雅的东西。它不需要为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)的集合,它们都是字符串,我需要添加具有正确类型的列,以便将来在两个数据帧之间进行联合

我目前有:

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 }
我明白了

这是一个字符串,所以我得到:

org.apache.spark.sql.catalyst.parser.ParseException: mismatched input '.' expecting {<EOF>, '('}(line 1, pos 3)
== SQL == org.apache.spark.sql.types.StringType
---^^^
org.apache.spark.sql.catalyst.parser.ParseException:输入不匹配。“”应为{,('})(第1行,位置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(到:字符串):列

使用规范字符串将列强制转换为其他数据类型 类型的表示形式

您还可以扫描所有数据类型:

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))

Spark在
cast
函数中接受字符串。支持的值有:
string
boolean
byte
short
int
long
float
double
decimal
date
日期
时间戳
这就是答案(我快了几秒钟;))谢谢,但你推荐的是我提到的不那么优雅的方法。它需要将“StringType”匹配到“string”,将“IntegerType”匹配到“int”等等。就像我说的,我可以这样做,但我想要一些不需要这样做的东西。请检查我的编辑,这不是我正在寻找的解决方案。这或我不完全理解你的建议和一个例子会有所帮助。谢谢,这不完全是我所希望的,但它是有效的:)。您创建的typeMap:scala.collection.immutable.Map[String,org.apache.spark.sql.types.DataType]是自动完成的,如果将来向包中添加新类型,您推荐的解决方案(与一系列ifs不同)将保持不变,因此这就是我需要的。谢谢。@UrVal您仍然可以在数据帧上迭代并在内部使用此映射,就像您的示例中的
.cast(typeMap(i._2))
是的,我在接受答案之前检查了它,它成功了,谢谢:)
val types = classOf[DataTypes]
    .getDeclaredFields()
    .filter(f => java.lang.reflect.Modifier.isStatic(f.getModifiers()))
    .map(f => f.get(new DataTypes()).asInstanceOf[DataType])
val typeMap = types.map(t => (t.getClass.getSimpleName.replace("$", ""), t)).toMap
column.cast(typeMap(yourType))