扩展 PySpark DataFrame 的数组列
Expand array Column of PySpark DataFrame
我必须使用下面的数据将 DataFrame 转换为 GraphFrame。让我们考虑数据框中的一列作者,其中包含如下所示的字符串数组:
+-----------+------------------------------------+
|ArticlePMID| Authors |
+-----------+------------------------------------+
| PMID1 |['Author 1', 'Author 2', 'Author 3']|
| PMID2 |['Author 4', 'Author 5'] |
+-----------+------------------------------------+
在数据 table 中,我们有一个在同一篇论文上合作的作者列表。现在我想将第二列扩展到一个包含以下结构的新数据框中:
+---------------+---------------+
| Collaborator1 | Collaborator2 |
+---------------+---------------+
| 'Author 1' | 'Author 2' |
| 'Author 1' | 'Author 3' |
| 'Author 2' | 'Author 3' |
| 'Author 4' | 'Author 5' |
+---------------+---------------+
我尝试使用 explode 函数,但这只会将数组扩展为单个作者列,并且我失去了协作网络。
有人能告诉我如何解决这个问题吗?
只要您使用的是 pyspark 2.1 或更高版本,就可以使用 posexplode
后跟 join
:
先用数组中的位置爆炸:
from pyspark.sql.functions import posexplode
exploded = df.select("*", posexplode("Authors").alias("pos", "Author"))
exploded.show()
#+-----------+--------------------+---+--------+
#|ArticlePMID| Authors|pos| Author|
#+-----------+--------------------+---+--------+
#| PMID1|[Author 1, Author...| 0|Author 1|
#| PMID1|[Author 1, Author...| 1|Author 2|
#| PMID1|[Author 1, Author...| 2|Author 3|
#| PMID2|[Author 4, Author 5]| 0|Author 4|
#| PMID2|[Author 4, Author 5]| 1|Author 5|
#+-----------+--------------------+---+--------+
现在在 ArticlePMID
列和 select 仅将左侧 table 的 pos
小于右侧的列与分解后的 DataFrame 连接起来边 table 的。
exploded.alias("l").join(exploded.alias("r"), on="ArticlePMID", how="inner")\
.where("l.pos < r.pos")\
.selectExpr("l.Author AS Collaborator1", "r.Author AS Collaborator2")\
.show()
#+-------------+-------------+
#|Collaborator1|Collaborator2|
#+-------------+-------------+
#| Author 1| Author 2|
#| Author 1| Author 3|
#| Author 2| Author 3|
#| Author 4| Author 5|
#+-------------+-------------+
使用 pos
进行过滤是为了避免同时列出同一对作者。
我必须使用下面的数据将 DataFrame 转换为 GraphFrame。让我们考虑数据框中的一列作者,其中包含如下所示的字符串数组:
+-----------+------------------------------------+
|ArticlePMID| Authors |
+-----------+------------------------------------+
| PMID1 |['Author 1', 'Author 2', 'Author 3']|
| PMID2 |['Author 4', 'Author 5'] |
+-----------+------------------------------------+
在数据 table 中,我们有一个在同一篇论文上合作的作者列表。现在我想将第二列扩展到一个包含以下结构的新数据框中:
+---------------+---------------+
| Collaborator1 | Collaborator2 |
+---------------+---------------+
| 'Author 1' | 'Author 2' |
| 'Author 1' | 'Author 3' |
| 'Author 2' | 'Author 3' |
| 'Author 4' | 'Author 5' |
+---------------+---------------+
我尝试使用 explode 函数,但这只会将数组扩展为单个作者列,并且我失去了协作网络。
有人能告诉我如何解决这个问题吗?
只要您使用的是 pyspark 2.1 或更高版本,就可以使用 posexplode
后跟 join
:
先用数组中的位置爆炸:
from pyspark.sql.functions import posexplode
exploded = df.select("*", posexplode("Authors").alias("pos", "Author"))
exploded.show()
#+-----------+--------------------+---+--------+
#|ArticlePMID| Authors|pos| Author|
#+-----------+--------------------+---+--------+
#| PMID1|[Author 1, Author...| 0|Author 1|
#| PMID1|[Author 1, Author...| 1|Author 2|
#| PMID1|[Author 1, Author...| 2|Author 3|
#| PMID2|[Author 4, Author 5]| 0|Author 4|
#| PMID2|[Author 4, Author 5]| 1|Author 5|
#+-----------+--------------------+---+--------+
现在在 ArticlePMID
列和 select 仅将左侧 table 的 pos
小于右侧的列与分解后的 DataFrame 连接起来边 table 的。
exploded.alias("l").join(exploded.alias("r"), on="ArticlePMID", how="inner")\
.where("l.pos < r.pos")\
.selectExpr("l.Author AS Collaborator1", "r.Author AS Collaborator2")\
.show()
#+-------------+-------------+
#|Collaborator1|Collaborator2|
#+-------------+-------------+
#| Author 1| Author 2|
#| Author 1| Author 3|
#| Author 2| Author 3|
#| Author 4| Author 5|
#+-------------+-------------+
使用 pos
进行过滤是为了避免同时列出同一对作者。