Pyspark 使用点或括号表示法选择时列的空值,但使用UDF时不为空值

Pyspark 使用点或括号表示法选择时列的空值,但使用UDF时不为空值,pyspark,apache-spark-sql,pyspark-dataframes,spark-cassandra-connector,Pyspark,Apache Spark Sql,Pyspark Dataframes,Spark Cassandra Connector,我试图清理一些嵌套数据并提取我关心的字段 嵌套值的模式为: |-- maritalstatus: struct (nullable = true) | |-- id: string (nullable = true) | |-- text_: string (nullable = true) | |-- text__extensions: array (nullable = true) | | |-- element: string (containsNu

我试图清理一些嵌套数据并提取我关心的字段

嵌套值的模式为:

 |-- maritalstatus: struct (nullable = true)
 |    |-- id: string (nullable = true)
 |    |-- text_: string (nullable = true)
 |    |-- text__extensions: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
 |    |-- extension: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
我想将文本字段提取为它自己的列

我试过: df.选择colmaritalstatus.text\uux.show 和df.selectcolmaritalstatus[text.]显示,但返回:

+-----+
|text_|
+-----+
| null|
| null|
 ...
| null|
+-----+
当我将自定义项定义为:

def getMaritalStatus(ms):
    return ms.text_
gms = udf(getMaritalStatus, StringType())
并执行df.selectgmscolmaritalstatus.show返回我期望的数据

有趣的是,我有另一个嵌套的结构字段,它的结构类似,但以数字作为键而不是名称,并且我可以使用df.selectcolbirthdate[0]。show notation

出生日期的模式:

root
 |-- birthdate: struct (nullable = true)
 |    |-- 0: date (nullable = true)
 |    |-- 1: integer (nullable = true)
是否仍然可以在不使用UDF的情况下提取maritalstatus.text?我听说UDF的性能不如其他方法

卡桑德拉表格结构:

CREATE TABLE keyspace.patient (
    id text PRIMARY KEY,
    active boolean,
    active_extensions list<text>,
    address list<frozen<address>>,
    birthdate frozen<tuple<date, int>>,
    birthdate_extensions list<text>,
    communication list<frozen<patient_communication>>,
    contact list<frozen<patient_contact>>,
    contained list<frozen<tuple<text, text, text>>>,
    deceasedboolean boolean,
    deceasedboolean_extensions list<text>,
    deceaseddatetime frozen<tuple<timestamp, text, int>>,
    deceaseddatetime_extensions list<text>,
    extension list<text>,
    gender text,
    gender_extensions list<text>,
    generalpractitioner list<text>,
    identifier list<frozen<identifier>>,
    implicitrules text,
    implicitrules_extensions list<text>,
    language text,
    language_extensions list<text>,
    link list<frozen<patient_link>>,
    managingorganization text,
    maritalstatus frozen<codeableconcept>,
    meta frozen<meta>,
    modifierextension list<text>,
    multiplebirthboolean boolean,
    multiplebirthboolean_extensions list<text>,
    multiplebirthinteger int,
    multiplebirthinteger_extensions list<text>,
    name list<frozen<humanname>>,
    photo list<frozen<attachment>>,
    telecom list<frozen<contactpoint>>,
    text_ frozen<narrative>
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';
使用pysparksql 可以使用查询嵌套数据。对于数组,使用爆炸函数

df=df.selectmaritalstatus.*.show1,False

df=df.selectmartialstatus.text\uu0.aliastext\u new.show1,False

您可以使用[name]访问列中的嵌套值,也可以使用.getItem函数执行相同操作。列可以显式包装到col中,也可以使用语法dataframe[Column\u name]。如果我们采集样本数据,如下所示:

从pyspark.sql.functions导入col rdd=sc.parallelize['{maritalstatus:{id:some_id,text:some_text,text_u扩展:[1,2],扩展:[e1,e2]}}'] df=spark.read.jsonrdd 然后所有三个电话:

df.选择df['maritalstatus']['text\'].显示 df.选择col'maritalstatus'['text\'].显示 df.选择col'maritalstatus'.getItem'text.'显示 将产生相同的结果:

+-------------------+
|maritalstatus.text_|
+-------------------+
|          some_text|
+-------------------+


是否可以提供一些样本数据?使用哪种版本的Spark&Spark Cassandra连接器?还有,Cassandra版本开放源Cassandra 3.11.9、spark-3.0.1和spark-Cassandra-connector_2.12:3.0.0。我正在运行pyspark命令:pyspark-packages com.datastax.spark:spark-cassandra-connector_2.12:3.0.0-conf spark.sql.extensions=com.datastax.spark.connector.cassandrasparkextensions当我运行第一个命令时,它会像我所希望的那样分解数据,但是如果我尝试进一步选择只获取maritalstatus.text字段,它变为空:df.selectmaritalstatus.*.show1``++--+--+--+--+--+--+--+--+--+--id |编码|文本|文本|扩展|+--+--+--+--+--+--+--null |[,S |[]|+--+--+--+--+--+--+``RAWCATIENT.selectmaritalstatus.*.selecttext.\uU1是null@HarrisonT你能试试第二个吗?还有,如果你能共享一个精确的样本数据。第二个会立即失败。我正在使用spark Cassandra连接器从Cassandra中提取数据,所以我不确定是否有好的方法来轻松共享数据?嗨,Alex,谢谢你的回复。我可以确认,当我像你一样使用JSON时,这些都可以工作,但这种语法对于我的患者的“婚姻状况”字段仍然不起作用。我正在使用spark Cassandra连接器从Cassandra中提取数据,所以我不确定是否有一种方便共享数据的好方法?你能共享struc吗你的表的真实性-只需更新问题,我没有用Cassandra尝试,因为我今天没有访问服务器的权限
+-------------------+
|maritalstatus.text_|
+-------------------+
|          some_text|
+-------------------+