String Indexer, CountVectorizer Pyspark в одной строке - PullRequest
0 голосов
/ 07 февраля 2020

Привет, я столкнулся с проблемой, из-за которой у меня есть строки с двумя столбцами массива слов.

column1, column2
["a", "b" ,"b", "c"], ["a","b", "x", "y"]

В основном я хочу посчитать вхождение каждого слова между столбцами, чтобы в итоге получить два массивы:

[1, 2, 1, 0, 0], 
[1, 1, 0, 1, 1]

Таким образом, «a» появляется один раз в каждом массиве, «b» появляется дважды в столбце 1 и один раз в столбце 2, «c» появляется только в столбце 1, «x» и «y» только в колонке2. И так далее и так далее.

Я пытался взглянуть на функцию CountVectorizer из библиотеки ml, но не уверен, работает ли она по строкам, массивы в каждом столбце могут быть очень большими? И 0 значений (где одно слово появляется в одном столбце, а не в другом), похоже, не переносится.

Любая помощь приветствуется.

1 Ответ

1 голос
/ 08 февраля 2020

Для Spark 2.4+ это можно сделать с помощью API DataFrame и встроенных функций массива.

Сначала получите все слова для каждой строки, используя функцию array_union. Затем используйте функцию transform для преобразования массива слов, где для каждого элемента рассчитайте количество вхождений в каждом столбце, используя size и array_remove функции:

df = spark.createDataFrame([(["a", "b", "b", "c"], ["a", "b", "x", "y"])], ["column1", "column2"])

df.withColumn("words", array_union("column1", "column2")) \
  .withColumn("occ_column1",
              expr("transform(words, x -> size(column1) - size(array_remove(column1, x)))")) \
  .withColumn("occ_column2",
              expr("transform(words, x -> size(column2) - size(array_remove(column2, x)))")) \
  .drop("words") \
  .show(truncate=False)

Вывод:

+------------+------------+---------------+---------------+
|column1     |column2     |occ_column1    |occ_column2    |
+------------+------------+---------------+---------------+
|[a, b, b, c]|[a, b, x, y]|[1, 2, 1, 0, 0]|[1, 1, 0, 1, 1]|
+------------+------------+---------------+---------------+
...