Раздел Pyspark по большинству подсчетов - PullRequest
1 голос
/ 09 июля 2020

У меня вопрос,

У меня есть такой набор данных:

id / color
1 / red
2 / green
2 / green 
2 / blue
3 / blue
4 / yellow 
4 / pink
5 / red

, и я хотел бы сгруппировать его по идентификатору и сохранить наиболее частый цвет, чтобы иметь что-то вроде этого : (в случае розыгрыша выбирайте случайным образом, это нормально, или лучшее решение, если оно есть)

id / most_color
1 / red
2 / green
3 / blue
4 / yellow
5 / red

Я пробовал такие вещи, как:

display(dataset.select("id","color").
        dropDuplicates().
        withColumn("most_color",count("color").over(w)))

или примерно так:

dataset2= (dataset.select("id","color").
                              withColumn("most_color", dataset["color"]).
                              groupBy("id").
                              agg(count('color').
                              alias('count').
                              filter(column('count') == max(count))))

display(dataset2)

всем спасибо

1 Ответ

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

Вы можете использовать оконную функцию row_number () для достижения этой цели

from pyspark.sql import functions as F
from pyspark.sql import Window as W    
_w = W.partitionBy('id').orderBy(F.col('id').desc())
_w = W.partitionBy('id').orderBy(F.col('id').desc())
df_final = df_final.withColumn('rn_no', F.row_number().over(_w))
df_final  = df_final.filter(F.col('rn_no') == 1)
df_final.show()

Вывод

id / most_color
1 / red
2 / green
3 / blue
4 / yellow
5 / red

Модифицированная версия: это даст вам наиболее часто используемое / появляющееся значение в группе -

Вход

df_a = spark.createDataFrame([(1,'red'),(2,'green'),(2,'green'),(2,'blue'),(3,'blue'),(4,'yellow'),(4,'pink'),(5,'red')],[ "id","color"])

+---+------+
| id| color|
+---+------+
|  1|   red|
|  2| green|
|  2| green|
|  2|  blue|
|  3|  blue|
|  4|yellow|
|  4|  pink|
|  5|   red|
+---+------+

# First Group the values to get the max appeared color in a group
df = df_a.groupBy('id','color').agg(F.count('color').alias('count')).orderBy(F.col('id'))

# Now, make a partition and sort of the decending order for each window of ID and take the first value
_w = W.partitionBy('id').orderBy(F.col('count').desc())
df_a = df.withColumn('rn_no', F.row_number().over(_w))
df_a = df_a.filter(F.col('rn_no') == F.lit('1'))

Выход

df_a.show()
+---+-----+-----+-----+
| id|color|count|rn_no|
+---+-----+-----+-----+
|  1|  red|    1|    1|
|  2|green|    2|    1|
|  3| blue|    1|    1|
|  4| pink|    1|    1|
|  5|  red|    1|    1|
+---+-----+-----+-----+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...