Python 创建特定于数据帧的架构:以大写字母开头的StructField
我为这篇冗长的帖子道歉,因为它看起来很简单,但我想给出完整的上下文 在DataRicks中,我基于特定的模式定义创建一个数据“行”,然后将该行插入一个空数据框(也基于相同的特定模式) 架构定义如下所示:Python 创建特定于数据帧的架构:以大写字母开头的StructField,python,pyspark,schema,azure-databricks,pyspark-dataframes,Python,Pyspark,Schema,Azure Databricks,Pyspark Dataframes,我为这篇冗长的帖子道歉,因为它看起来很简单,但我想给出完整的上下文 在DataRicks中,我基于特定的模式定义创建一个数据“行”,然后将该行插入一个空数据框(也基于相同的特定模式) 架构定义如下所示: myschema_xb = StructType( [ StructField("_xmlns", StringType(), True), StructField("_Version", DoubleType(), True), StructField("MyIds
myschema_xb = StructType(
[
StructField("_xmlns", StringType(), True),
StructField("_Version", DoubleType(), True),
StructField("MyIds",
ArrayType(
StructType(
[
StructField("_ID", StringType(), True),
StructField("_ID_Context", StringType(), True),
StructField("_Type", LongType(), True),
]
),
True
),
True
),
]
)
因此,行条目是:
myRow = Row(
_xmlns="http://some.where.com",
_Version=12.3,
MyIds=[
Row(
_ID="XY",
_ID_Context="Exxwhy",
_Type=9
),
Row(
_ID="9152",
_ID_Context="LNUMB",
_Type=21
),
]
)
最后,databricks笔记本代码为:
mydf = spark.createDataFrame(sc.emptyRDD(), myschema_xb)
rows = [myRow]
rdf = spark.createDataFrame(rows, myschema_xb)
appended = mydf.union(rdf)
调用rdf=spark.createDataFrame(rows,myschema_xb)
会导致异常:
ValueError:StructType为意外元组“h”
现在我想知道的是,如果我将元素myid
更改为myid
(即小写的第一个字母),代码可以工作,并且我的新数据框(追加的
)只有一行数据
这个异常是什么意思&当我改变元素的大小写时,为什么它会消失
(仅供参考,我们的databricks运行时环境是Scala 2.11)
谢谢。问题应该来自行对象如何对键/字段进行排序,来自: Row可用于通过使用命名参数创建Row对象,字段将按名称排序 在
myschema\u xb
中,这三列的定义顺序为[\u xmlns,\u Version,myid]
。使用键定义myRow时:(\u xmlns,\u Version,myid)
,实际生成的Row对象将是:
Row(MyIds=[Row(_ID='XY', _ID_Context='Exxwhy', _Type=9), Row(_ID='9152', _ID_Context='LNUMB', _Type=21)], _Version=12.3, _xmlns='http://some.where.com')
它将myid
移动到第一列,这与模式不匹配,因此产生错误。当您使用小写列名myid
时,行对象中的键被排序为[''u Version'、''u xmlns'、'myid']
,其在右列中有myid
,但\u Version
和\u xmls
已切换。这不会产生错误,因为简单数据类型可以通过类型转换,但生成的数据帧不正确
要解决此问题,您应该设置一个类似行的类并自定义键的顺序,以确保字段的顺序与架构中显示的顺序完全匹配:
from pyspark.sql import Row
MyOuterROW = Row('_xmlns', '_Version', 'MyIds')
MyInnerRow = Row('_ID', '_ID_Context', '_Type')
myRow = MyOuterROW(
"http://some.where.com",
12.3,
[
MyInnerROW("XY", "Exxwhy", 9),
MyInnerROW("9152", "LNUMB", 21)
]
)
print(myRow)
#Row(_xmlns='http://some.where.com', _Version=12.3, MyIds=[Row(_ID='XY', _ID_Context='Exxwhy', _Type=9), Row(_ID='9152', _ID_Context='LNUMB', _Type=21)])
rdf = spark.createDataFrame([myRow], schema=myschema_xb)