首页 > 解决方案 > 计算 pyspark 数据框中的出现次数

问题描述

如图所示,我需要计算 pyspark 数据框中重复值的出现次数。简而言之,当值相同时,它会累加,直到值不同。当值不同时,计数被重置。我需要它在一个专栏中。

我有的:

+------+
| val  |
+------+
| 0    | 
| 0    | 
| 0    |
| 1    |
| 1    |
| 2    |
| 2    |
| 2    |
| 3    |
| 3    |
| 3    |
| 3    |
+------+

我需要的:

+------+-----+
| val  |ocurr| 
+------+-----+
| 0    | 0   | 
| 0    | 1   | 
| 0    | 2   |
| 1    | 0   |
| 1    | 1   |
| 2    | 0   |
| 2    | 1   |
| 2    | 2   |
| 3    | 0   |
| 3    | 1   |
| 3    | 2   |
| 3    | 3   |
+------+-----+

标签: pythonamazon-web-servicespysparkapache-spark-sqlaws-glue

解决方案


使用whenlag函数对相同的并发值进行分组,并使用row_number来获取计数。您应该有一个适当的排序列,我的临时排序列id不好,因为它不能保证保留顺序。

df = spark.createDataFrame([0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 0, 0, 0], 'int').toDF('val')

from pyspark.sql.functions import *
from pyspark.sql import Window

w1 = Window.orderBy('id')
w2 = Window.partitionBy('group').orderBy('id')

df.withColumn('id', monotonically_increasing_id()) \
  .withColumn('group', sum(when(col('val') == lag('val', 1, 1).over(w1), 0).otherwise(1)).over(w1)) \
  .withColumn('order', row_number().over(w2) - 1) \
  .orderBy('id').show()

+---+---+-----+-----+
|val| id|group|order|
+---+---+-----+-----+
|  0|  0|    1|    0|
|  0|  1|    1|    1|
|  0|  2|    1|    2|
|  1|  3|    2|    0|
|  1|  4|    2|    1|
|  2|  5|    3|    0|
|  2|  6|    3|    1|
|  2|  7|    3|    2|
|  3|  8|    4|    0|
|  3|  9|    4|    1|
|  3| 10|    4|    2|
|  3| 11|    4|    3|
|  0| 12|    5|    0|
|  0| 13|    5|    1|
|  0| 14|    5|    2|
+---+---+-----+-----+

推荐阅读