Apache spark pyspark在字符串中嵌套列
我和Pypark一起工作。我从csv加载了一个Apache spark pyspark在字符串中嵌套列,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我和Pypark一起工作。我从csv加载了一个DataFrame,其中包含以下架构: root |-- id: string (nullable = true) |-- date: date (nullable = true) |-- users: string (nullable = true) 如果我显示前两行,它看起来像: +---+----------+---------------------------------------------------+ | id|
DataFrame
,其中包含以下架构:
root
|-- id: string (nullable = true)
|-- date: date (nullable = true)
|-- users: string (nullable = true)
如果我显示前两行,它看起来像:
+---+----------+---------------------------------------------------+
| id| date|users |
+---+----------+---------------------------------------------------+
| 1|2017-12-03|{"1":["xxx","yyy","zzz"],"2":["aaa","bbb"],"3":[]} |
| 2|2017-12-04|{"1":["uuu","yyy","zzz"],"2":["aaa"],"3":[]} |
+---+----------+---------------------------------------------------+
我想创建一个新的DataFrame
,其中包含由每个元素分隔的“user”字符串。我想要类似的
id user_id user_product
1 1 xxx
1 1 yyy
1 1 zzz
1 2 aaa
1 2 bbb
1 3 <null>
2 1 uuu
etc...
这将返回正确的架构:
root
|-- id: string (nullable = true)
|-- test: struct (nullable = true)
| |-- user_id: string (nullable = true)
| |-- product_list: struct (nullable = true)
| | |-- product: string (nullable = true)
但是,当我显示“test”结构的任何部分时,它返回的是nulls
,而不是值,例如
user\u df.select('test.user\u id').show()
返回test.user\u id:
+-------+
|user_id|
+-------+
| null|
| null|
+-------+
也许我不应该使用来自_json的
,因为users字符串不是纯json。关于我可以采取的方法,有什么帮助吗?您不需要使用来自json的。您必须将分解
两次,一次用于用户id
,一次用于用户
导入pyspark.sql.F函数
df=sql.createDataFrame([
(1,'2017-12-03',{“1”:[“xxx”,“yyy”,“zzz”],“2”:[“aaa”,“bbb”],“3”:[]),
(2,'2017-12-04',{“1”:[“uuu”,“yyy”,“zzz”],“2”:[“aaa”],“3”:[]},
['id'、'date'、'users']
)
df=df.select('id','date',F.explode('users')。别名('user_id','users'))\
.select('id','date','user_id',F.explode('users')。别名('users'))
df.show()
+---+----------+-------+-----+
|id |日期|用户| id |用户|
+---+----------+-------+-----+
|1 | 2017-12-03 | 1 | xxx|
|1 | 2017-12-03 | 1 | yyy|
|1 | 2017-12-03 | 1 | zzz|
|1 | 2017-12-03 | 2 | aaa|
|1 | 2017-12-03 | 2 | bbb|
|2 | 2017-12-04 | 1 | uuu|
|2 | 2017-12-04 | 1 | yyy|
|2 | 2017-12-04 | 1 | zzz|
|2 | 2017-12-04 | 2 | aaa|
+---+----------+-------+-----+
模式应符合数据的形状。不幸的是,json中的只支持StructType(…)
或ArrayType(StructType(…))
,除非您能保证所有记录都具有相同的密钥集,否则在这里就没有用了
相反,您可以使用UserDefinedFunction
:
导入json
从pyspark.sql.functions导入explode,udf
df=spark.createDataFrame([
(1,“2017-12-03”、“{”1:[“xxx”、“yyy”、“zzz”]、“2:[“aaa”、“bbb”]、“3:[]}”),
(2),“2017-12-04”,“1”:[“uuu”,“yyy”,“zzz”],“2”:[“aaa”],“3”:[]}],
(“id”、“日期”、“用户”)
)
@udf(“地图”)
def解析:
尝试:
返回json.loads
除:
通过
(df)
.选择(“id”、“日期”,
分解(解析(“用户”)。别名(“用户id”、“用户产品”))
.withColumn(“用户产品”,explode(“用户产品”))
.show())
# +---+----------+-------+------------+
#| id |日期|用户| id |用户|产品|
# +---+----------+-------+------------+
#| 1 | 2017-12-03 | 1 | xxx|
#| 1 | 2017-12-03 | 1 | yyy|
#| 1 | 2017-12-03 | 1 | zzz|
#| 1 | 2017-12-03 | 2 | aaa|
#| 1 | 2017-12-03 | 2 | bbb|
#| 2 | 2017-12-04 | 1 | uuu|
#| 2 | 2017-12-04 | 1 | yyy|
#| 2 | 2017-12-04 | 1 | zzz|
#| 2 | 2017-12-04 | 2 | aaa|
# +---+----------+-------+------------+