PySpark - 使用爆炸功能后添加行号

use*_*036 8 row-number explode apache-spark pyspark

我正在做一个 nlp 项目,并且有包含多个句子的评论。我正在使用 Spark-nlp 包,该包输出一列,其中包含每条评论中的句子列表。我正在使用爆炸为每个句子创建一行,但我想添加编号,这样我就知道哪个句子是第一个、第二个等。我不知道如何使用 row_number() 因为我真的没有任何东西可以 orderBy 。

我的数据如下所示:

REVIEW_ID REVIEW_COMMENTS     SENTENCES_LIST           
    1     Hi. Sent1. Sent2.   [Hi., Sent1., Sent2.]   
    2     Yeah. Ok.           [Yeah., Ok.]  
Run Code Online (Sandbox Code Playgroud)

这就是我想要的样子:

REVIEW_ID REVIEW_COMMENTS     SENTENCES_LIST           SENTENCE  SENT_NUMBER
    1     Hi. Sent1. Sent2.   [Hi., Sent1., Sent2.]    Hi.       1
    1     Hi. Sent1. Sent2.   [Hi., Sent1., Sent2.]    Sent1.    2
    1     Hi. Sent1. Sent2.   [Hi., Sent1., Sent2.]    Sent2.    3
    2     Yeah. Ok.           [Yeah., Ok.]             Yeah.     1
    2     Yeah. Ok.           [Yeah., Ok.]             Ok.       2
Run Code Online (Sandbox Code Playgroud)

我正在使用下面的代码,但不确定如何使用 row_number(),因为除了它放置在 SENTENCES_LIST 中之外,我没有可用作“orderBy”的列。

df2 = df.withColumn('SENTENCE', F.explode('SENTENCES_LIST'))
df3 = df2.withColumn('SENT_NUMBER',row_number().over(Window.partitionBy('REVIEW_ID').orderBy('????'))) 
Run Code Online (Sandbox Code Playgroud)

mur*_*ash 5

对于,您可以与高阶函数一起Spark2.4+使用explodetransform.

from pyspark.sql import functions as F

df.withColumn("list", F.explode(F.expr("""transform(SENTENCES_LIST,(x,i)-> struct(x as SENTENCE,(i+1) as SENT_NUMBER))""")))\
  .select("*", "list.*").show()

#+---------+-----------------+--------------------+-----------+--------+-----------+
#|REVIEW_ID|  REVIEW_COMMENTS|      SENTENCES_LIST|       list|SENTENCE|SENT_NUMBER|
#+---------+-----------------+--------------------+-----------+--------+-----------+
#|        1|Hi. Sent1. Sent2.|[Hi., Sent1., Sen...|   [Hi., 1]|     Hi.|          1|
#|        1|Hi. Sent1. Sent2.|[Hi., Sent1., Sen...|[Sent1., 2]|  Sent1.|          2|
#|        1|Hi. Sent1. Sent2.|[Hi., Sent1., Sen...|[Sent2., 3]|  Sent2.|          3|
#|        2|        Yeah. Ok.|        [Yeah., Ok.]| [Yeah., 1]|   Yeah.|          1|
#|        2|        Yeah. Ok.|        [Yeah., Ok.]|   [Ok., 2]|     Ok.|          2|
#+---------+-----------------+--------------------+-----------+--------+-----------+
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,你的代码有效,但我最终使用了: `df.select('*', F.posexplode('SENTENCES_LIST').alias('SENT_NUMBER', 'SENTENCE'))` 更合适 (9认同)
  • 回想起来,与poseexplode相比,这有点过分了。谢谢@pault (2认同)