LDr*_*opl 4 apache-spark apache-spark-sql pyspark
我有一个包含不同列的数据框,其中一列是结构数组:
+----------+---------+--------------------------------------+
|id |title | values|
+----------+---------+--------------------------------------+
| 1 | aaa | [{name1, id1}, {name2, id2},...]|
| 2 | bbb | [{name11, id11}, {name22, id22},...]|
Run Code Online (Sandbox Code Playgroud)
此列的 df 架构如下所示:
|-- values: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- name: string (nullable = true)
| | |-- id: long (nullable = true)
Run Code Online (Sandbox Code Playgroud)
我想从这个数组列中提取每个值,如下所示:
+----------+---------+--------------+
|id |title |name | _id|
+----------+---------+--------------+
| 1 | aaa | name1 | id1 |
| 1 | aaa | name2 | id2 |
| 2 | bbb | name11| id11 |
| 2 | bbb | name22| id22 |
Run Code Online (Sandbox Code Playgroud)
我想出了如何提取数组的单个项目:
df = df.withColumn("name", df["values"].getItem(0).name)\
.withColumn("_id", df["id"].getItem(0).id)\
Run Code Online (Sandbox Code Playgroud)
但我不知道如何将它应用于整个数组长度。我可能应该做这样的事情:
for index in range(len(df.values)):
df = df.withColumn("name", df["values"].getItem(index).name)\
.withColumn("_id", df["id"].getItem(index).id)\
Run Code Online (Sandbox Code Playgroud)
你能帮我解决吗?谢谢!
小智 6
只需explode选择
from pyspark.sql.functions import col, explode
df.withColumn("values", explode("values")).select(
"*", col("values")["name"].alias("name"), col("values")["id"].alias("id")
)
Run Code Online (Sandbox Code Playgroud)
进一步扩展解决方案。您可以使用这种方法通过使用 col("col_name.*") 选择结构体字段中的所有元素,而不是单独提取每个结构体元素。
from pyspark.sql.functions import col, explode
df.withColumn("values", explode("values")).select(
"*",col("values.*")
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6931 次 |
| 最近记录: |