Групповой счет в PySpark - PullRequest
       12

Групповой счет в PySpark

0 голосов
/ 10 апреля 2019

У меня есть следующий фрейм данных:

---------------
id   | name   |
---------------
 1   | joe    |
 1   | john   |
 2   | jane   |
 3   | jo     |
---------------

Цель состоит в том, чтобы в случае дублирования столбца id добавить к нему возрастающий номер, начиная с 1.

В Пандах я могу сделать это следующим образом:

count_id = df.groupby(['id']).cumcount()
count_num = count_id.replace(0, '').astype(str)
df['id'] += count_num

Я пытался использовать ту же логику в PySpark, но безуспешно.

Результат должен быть:


id   | name   |
---------------
 1   | joe    |
 11  | john   |
 2   | jane   |
 3   | jo     |
---------------

Как мне добиться того же в PySpark? Любая помощь с благодарностью.

1 Ответ

1 голос
/ 10 апреля 2019

Чтобы воспроизвести этот вывод, вы можете использовать Window, чтобы получить row_number для каждого id, а затем concatдобавить его в id.

import pyspark.sql.functions as f
from pyspark.sql import Window

w = Window.partitionBy("id").orderBy("name")
df.withColumn("row_number", f.row_number().over(w)-1)\
    .withColumn(
        "id", 
        f.when(
            f.col("row_number") > 0, 
            f.concat(f.col("id"), f.col("row_number"))
        ).otherwise(f.col("id"))
    )\
    .drop("row_number")\
    .show()
#+---+----+
#| id|name|
#+---+----+
#|  1| joe|
#| 11|john|
#|  3|  jo|
#|  2|jane|
#+---+----+

Примечание : при этом столбец id преобразуется в столбец StringType, если его еще нет.


Чтобы получить результат, который вы первоначально указали в вопросе, в качестве желаемого результата, вам нужно добавить столбец подсчета групп в дополнение к вычислению номера строки.Объединять номер строки только в том случае, если число больше единицы.

import pyspark.sql.functions as f
from pyspark.sql import Window

w = Window.partitionBy("id")
df.withColumn("count", f.count("*").over(w))\
    .withColumn("row_number", f.row_number().over(w.orderBy("name")))\
    .withColumn(
        "id", 
        f.when(
            f.col("count") > 1, 
            f.concat(f.col("id"), f.col("row_number"))
        ).otherwise(f.col("id"))
    )\
    .drop("count", "row_number")\
    .show()
#+---+----+
#| id|name|
#+---+----+
#| 11| joe|
#| 12|john|
#|  3|  jo|
#|  2|jane|
#+---+----+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...