【发布时间】:2021-04-10 14:54:26
【问题描述】:
我正在使用一个相当大的镶木地板表,99.9% 的数据包含在单个键:值列中。例如:
# Cannot use hive metastore to access so we have to load this way
df = spark.read.parquet('hdfs://cluster/path/to/parquet') \
.select('id, 'version', 'details')
df.printSchema()
>> root
|-- id: string
|-- version: string
|-- details: map
| |-- key: string
| |-- value: struct
| | |-- complex_struct_1: struct
| | | |-- complex_substruct_1: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_struct_2: struct
| | | |-- complex_substruct_n: struct
| | | | |-- ...
| | | |-- ...
| | |-- complex_field_n: struct
有问题的列是 details,可能的键是 key_1、key_2、两者或无。我的问题是如何有效地仅选择属于 key_1 的子字段(例如选择 details['key_1'].complex_struct_1.complex_substruct_1.field)?
因为表不在 hive 元存储中,我不相信我可以在这里使用 spark.sql,或者如果有任何好处。我了解如何天真地加载数据库,选择整个详细信息列然后过滤,但鉴于详细信息列绝对庞大(数千个字段)并且我只想要一个小子集,我想利用列访问如果可能在这里。这是我可以更有效地做的事情,还是超出了镶木地板的能力?
【问题讨论】:
-
df.select(df.details['key_1'].complex_struct_1.complex_substruct_1.field)? -
@MykolaZotko 我正在尝试这些方面的东西,但该语法似乎不起作用:
TypeError: Invalid argument, not a string or column: <bound method alias of Column<b'details[key_1]'>> of type <class 'method'>. For column literals, use 'lit', 'array', 'struct' or 'create_map' function. -
试试
df.selectExpr("details['key_1'].complex_struct_1.complex_substruct_1.*")
标签: apache-spark pyspark apache-spark-sql parquet