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