扩展 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 进行过滤是为了避免同时列出同一对作者。