Сравните строки, чтобы образовать существительное в PySpark - PullRequest
1 голос
/ 13 июля 2020

У меня есть фреймворк Spark, где каждая строка является токеном из предложения и включает его часть речи. Я пытаюсь найти лучший способ сравнить одну строку с другой, чтобы создать самый длинный фрагмент существительного.

+------+-----------+---------------------------+--------+-------+-------+-----+
|REV_ID|    SENT_ID|                   SENTENCE|TOKEN_ID|  TOKEN|  LEMMA|  POS|
+------+-----------+---------------------------+--------+-------+-------+-----+
|     1|          1|Ice hockey game took hours.|       1|    Ice|    ice| NOUN|
|     1|          1|Ice hockey game took hours.|       2| hockey| hockey| NOUN|
|     1|          1|Ice hockey game took hours.|       3|   game|   game| NOUN|
|     1|          1|Ice hockey game took hours.|       4|   took|   take| VERB|
|     1|          1|Ice hockey game took hours.|       5|  hours|   hour| NOUN|

Я знаю, что for l oop неэффективен, но я не уверен, как еще получить желаемые результаты, как показано ниже:

+------+-----------+---------------------------+--------+-------+-------+-----+----------------+
|REV_ID|    SENT_ID|                   SENTENCE|TOKEN_ID|  TOKEN|  LEMMA|  POS|      NOUN_CHUNK|
+------+-----------+---------------------------+--------+-------+-------+-----+----------------+
|     1|          1|Ice hockey game took hours.|       1|    Ice|    ice| NOUN| ice hockey game|
|     1|          1|Ice hockey game took hours.|       2| hockey| hockey| NOUN| ice hockey game|
|     1|          1|Ice hockey game took hours.|       3|   game|   game| NOUN| ice hockey game|
|     1|          1|Ice hockey game took hours.|       4|   took|   take| VERB|            NULL|
|     1|          1|Ice hockey game took hours.|       5|  hours|   hour| NOUN|            hour|

1 Ответ

1 голос
/ 13 июля 2020

Попробуйте это с оконными функциями.

from pyspark.sql import functions as F
from pyspark.sql.window import Window

w=Window().partitionBy("SENT_ID").orderBy("TOKEN_ID")
w1=Window().partitionBy("SENT_ID", "list")

df\
  .withColumn("list", F.sum(F.when(F.col("POS")=='NOUN', F.lit(0)).otherwise(F.lit(1))).over(w))\
  .withColumn("list", F.expr("""IF(POS!='NOUN',null,list)"""))\
  .withColumn("NOUN_CHUNK", F.when(F.col("list").isNotNull(),F.array_join(F.collect_list("LEMMA").over(w1),' '))\
                             .otherwise(F.lit(None))).drop("list").orderBy("SENT_ID","TOKEN_ID").show()

#+------+-------+--------------------+--------+------+------+----+---------------+
#|REV_ID|SENT_ID|            SENTENCE|TOKEN_ID| TOKEN| LEMMA| POS|     NOUN_CHUNK|
#+------+-------+--------------------+--------+------+------+----+---------------+
#|     1|      1|Ice hockey game t...|       1|   Ice|   ice|NOUN|ice hockey game|
#|     1|      1|Ice hockey game t...|       2|hockey|hockey|NOUN|ice hockey game|
#|     1|      1|Ice hockey game t...|       3|  game|  game|NOUN|ice hockey game|
#|     1|      1|Ice hockey game t...|       4|  took|  take|VERB|           null|
#|     1|      1|Ice hockey game t...|       5| hours|  hour|NOUN|           hour|
#+------+-------+--------------------+--------+------+------+----+---------------+
...