我必须使用以下数据将DataFrame转换为GraphFrame。让我们考虑一个数据帧中的Authors列,其中包含一个字符串数组,如下所示:
+-----------+------------------------------------+
|ArticlePMID| Authors |
+-----------+------------------------------------+
| PMID1 |['Author 1', 'Author 2', 'Author 3']|
| PMID2 |['Author 4', 'Author 5'] |
+-----------+------------------------------------+
在数据表中,我们列出了在同一篇论文上一起合作的作者。现在,我想将第二列扩展为包含以下结构的新数据框:
+---------------+---------------+
| Collaborator1 | Collaborator2 |
+---------------+---------------+
| 'Author 1' | 'Author 2' |
| 'Author 1' | 'Author 3' |
| 'Author 2' | 'Author 3' |
| 'Author 4' | 'Author 5' |
+---------------+---------------+
我尝试使用explode函数,但是那样只能将数组扩展为单个作者列,而我失去了协作网络。
能不能告诉我如何解决这个问题?
答案 0 :(得分:2)
只要您使用的是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
列上将爆炸的DataFrame与其自身相连,并仅选择左侧表的pos
小于右侧表的列。
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
进行过滤是为了避免同时列出两种相同的作者对。