PySpark - удалить пробел в n-граммах - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь создать n-грамм из 3 букв, но Spark NGram вставляет пробел между каждой буквой. Я хочу удалить (или не производить) этот пробел. Я мог бы взорвать массив, удалить пробелы, а затем собрать массив, но это было бы очень дорогой операцией. Желательно также избегать создания пользовательских функций из-за проблем с производительностью пользовательских функций PySpark. Есть ли более дешевый способ сделать это, используя встроенные функции PySpark?

from pyspark.ml import Pipeline, Model, PipelineModel
from pyspark.ml.feature import Tokenizer, RegexTokenizer, StopWordsRemover, NGram
from pyspark.sql.functions import *


wordDataFrame = spark.createDataFrame([
    (0, "Hello I heard about Spark"),
    (1, "I wish Java could use case classes"),
    (2, "Logistic regression models are neat")
], ["id", "words"])

pipeline = Pipeline(stages=[
        RegexTokenizer(pattern="", inputCol="words", outputCol="tokens", minTokenLength=1),
        NGram(n=3, inputCol="tokens", outputCol="ngrams")
    ])

model = pipeline.fit(wordDataFrame).transform(wordDataFrame)

model.show()

Токовый выход:

+---+--------------------+--------------------+--------------------+
| id|               words|              tokens|              ngrams|
+---+--------------------+--------------------+--------------------+
|  0|Hi I heard about ...|[h, e, l, l, o,  ...|[h e l, e l l,   ...|
+---+--------------------+--------------------+--------------------+

, но требуется:

+---+--------------------+--------------------+--------------------+
| id|               words|              tokens|              ngrams|
+---+--------------------+--------------------+--------------------+
|  0|Hello I heard ab ...|[h, e, l, l, o,  ...|[hel, ell, llo,  ...|
+---+--------------------+--------------------+--------------------+

1 Ответ

2 голосов
/ 03 марта 2020

Этого можно добиться, используя функцию более высокого порядка transform и regex . ( spark2.4 + ) (при условии, что столбец ngarms имеет тип массива с типом строки)

#sampledataframe
df.show()
+---+----------------+---------------+--------------+
| id|           words|         tokens|        ngrams|
+---+----------------+---------------+--------------+
|  0|Hi I heard about|[h, e, l, l, o]|[h e l, e l l]|
+---+----------------+---------------+--------------+

from pyspark.sql import functions as F
df.withColumn("ngrams", F.expr("""transform(ngrams,x-> regexp_replace(x,"\ ",""))""")).show()

+---+----------------+---------------+----------+
| id|           words|         tokens|    ngrams|
+---+----------------+---------------+----------+
|  0|Hi I heard about|[h, e, l, l, o]|[hel, ell]|
+---+----------------+---------------+----------+
...