Apache spark 在pyspark中将自定义函数的输出从默认StringType转换为mapType

Apache spark 在pyspark中将自定义函数的输出从默认StringType转换为mapType,apache-spark,pyspark,pyspark-sql,Apache Spark,Pyspark,Pyspark Sql,我正在运行一个嵌套的pyspark SQL查询。在子查询中,我使用一个自定义函数返回父查询将使用explode的字典,以展开此字典结果。 问题是,即使我返回一个字典,主查询仍会将此列类型视为stringType,explode将无法工作 def ffk,vList:返回指令[k+v,v代表vList中的v] df2=sqlContext.createDataFrame[Rowa=1,b=1,Rowa=1,b=2] df2.RegisterEmptableTTT2 sqlContext.regis

我正在运行一个嵌套的pyspark SQL查询。在子查询中,我使用一个自定义函数返回父查询将使用explode的字典,以展开此字典结果。 问题是,即使我返回一个字典,主查询仍会将此列类型视为stringType,explode将无法工作

def ffk,vList:返回指令[k+v,v代表vList中的v] df2=sqlContext.createDataFrame[Rowa=1,b=1,Rowa=1,b=2] df2.RegisterEmptableTTT2 sqlContext.registerFunction'ff',ff spark.sqlselect a,bb from select a,ffa,collect_listb as bb from ttt2 group by a.show +--+-----+ |a | bb| +--+-----+ | 1|{2=1, 3=2}| +--+-----+ 但是当我在主查询中使用explode时

spark.sqlselect a,explodebb from select a,ffa,collect_listb as bb from ttt2 group by a.show AnalysisException:UC无法解析“explode\uu自动生成的子查询\u名称”。'bb`,因为数据类型不匹配:函数explode的输入应为数组或映射类型,而不是字符串;第1行位置10\n'Project[a178L,unsolvedAliasExplodeBB294,None]\n+-子查询\u自动生成\u子查询\u名称\n+-聚合[a178L],[a178L,ffa178L,收集\u列表b179L,0,0作为bb294]\n+-子查询ttt2\n+-逻辑RDD[a178L,b179L,mapfield180],false\n 如何将函数的输出转换为mapType或ArrayType?

您需要为用户定义的函数指定返回类型。默认情况下,registerFunction将返回类型设置为string。如果 键入helpsqlContext.registerFunction,您将看到:

registerFunctionself,name,f,returnType=StringType

除了名称和函数本身之外,还可以选择指定返回类型。 如果未将返回类型指定为默认字符串,则将自动进行转换 完成。对于任何其他返回类型,生成的对象必须与指定的类型匹配

在您的情况下,您需要执行以下操作:

从pyspark.sql.types导入* registerFunction'ff',ff,returnType=MapTypeStringType,IntegerType spark.sql 从a、ffa中选择a、bb,由a从ttt2组中收集B作为bb 显示 +--+----------+ |a | bb| +--+----------+ |1 |地图2->1,3->2| +--+----------+ spark.sql 选择a,从选择a中分解bb,ffa,通过a从ttt2组中收集列表B作为bb 显示 +--+--+---+ |a |键|值| +--+--+---+ | 1| 2| 1| | 1| 3| 2| +--+--+---+
这里我使用MapTypeStringType、IntegerType来指定它是字符串键到整数值的映射。您可能需要根据实际数据对其进行修改。

NP。我假设您的实际问题更复杂,但您可以避免使用udf,并在执行df2时获得相同的输出。使用列'key',f.col'a'+f.col'b'。选择'a','key',f.col'b'。别名'value'。显示f是pyspark.sql.functions的位置