将百分位数作为 SparkR 数据框中的一列
Get percentiles as a column in SparkR dataframe
我有一个如下所示的 Spark 数据框(虚拟数据),我想使用 SparkR 添加百分位数作为列:
UserId Values
U1 5
U2 50
U3 76
.
.
.
.
.
U1000 8
示例:
UserId Values Percentile
U1 5 0.011144
U2 50 0.212245
U3 76 0.811986
.
.
.
.
.
U1000 8 0.0134567
嗯,有一个函数,percent_rank
,但它只对 window 个分区进行操作;调整文档示例:
library(SparkR)
library(magrittr)
sparkR.version()
# [1] "2.2.0"
df <- createDataFrame(mtcars)
ws <- orderBy(windowPartitionBy("am"), "hp")
out <- select(df, over(percent_rank(), ws), df$hp, df$am)
out <- out %>% withColumnRenamed(colnames(out)[1], 'percentile') # get rid of the ridiculously long column name
head(out)
# percentile hp am
# 1 0.00000000 62 0
# 2 0.05555556 95 0
# 3 0.11111111 97 0
# 4 0.16666667 105 0
# 5 0.22222222 110 0
# 6 0.27777778 123 0
如果你不想要一个 window 分区而是一个全局百分位数,就像你的情况一样,我能想到的最简单的方法是首先添加一个虚拟常量列并按此分组,你随后可以下降。所以,这是上面的例子,但这次没有按 am
:
分区
df_new = df %>% withColumn("dummy", lit("N"))
ws <- orderBy(windowPartitionBy('dummy'), "hp")
out <- select(df_new, over(percent_rank(), ws), df_new$hp)
out <- out %>% withColumnRenamed(colnames(out)[1], 'percentile')
collect(out)
的结果是
percentile hp
1 0.00000000 52
2 0.03225806 62
3 0.06451613 65
4 0.09677419 66
5 0.09677419 66
6 0.16129032 91
7 0.19354839 93
8 0.22580645 95
9 0.25806452 97
10 0.29032258 105
11 0.32258065 109
12 0.35483871 110
13 0.35483871 110
14 0.35483871 110
15 0.45161290 113
16 0.48387097 123
17 0.48387097 123
18 0.54838710 150
19 0.54838710 150
20 0.61290323 175
21 0.61290323 175
22 0.61290323 175
23 0.70967742 180
24 0.70967742 180
25 0.70967742 180
26 0.80645161 205
27 0.83870968 215
28 0.87096774 230
29 0.90322581 245
30 0.90322581 245
31 0.96774194 264
32 1.00000000 335
我有一个如下所示的 Spark 数据框(虚拟数据),我想使用 SparkR 添加百分位数作为列:
UserId Values
U1 5
U2 50
U3 76
.
.
.
.
.
U1000 8
示例:
UserId Values Percentile
U1 5 0.011144
U2 50 0.212245
U3 76 0.811986
.
.
.
.
.
U1000 8 0.0134567
嗯,有一个函数,percent_rank
,但它只对 window 个分区进行操作;调整文档示例:
library(SparkR)
library(magrittr)
sparkR.version()
# [1] "2.2.0"
df <- createDataFrame(mtcars)
ws <- orderBy(windowPartitionBy("am"), "hp")
out <- select(df, over(percent_rank(), ws), df$hp, df$am)
out <- out %>% withColumnRenamed(colnames(out)[1], 'percentile') # get rid of the ridiculously long column name
head(out)
# percentile hp am
# 1 0.00000000 62 0
# 2 0.05555556 95 0
# 3 0.11111111 97 0
# 4 0.16666667 105 0
# 5 0.22222222 110 0
# 6 0.27777778 123 0
如果你不想要一个 window 分区而是一个全局百分位数,就像你的情况一样,我能想到的最简单的方法是首先添加一个虚拟常量列并按此分组,你随后可以下降。所以,这是上面的例子,但这次没有按 am
:
df_new = df %>% withColumn("dummy", lit("N"))
ws <- orderBy(windowPartitionBy('dummy'), "hp")
out <- select(df_new, over(percent_rank(), ws), df_new$hp)
out <- out %>% withColumnRenamed(colnames(out)[1], 'percentile')
collect(out)
的结果是
percentile hp
1 0.00000000 52
2 0.03225806 62
3 0.06451613 65
4 0.09677419 66
5 0.09677419 66
6 0.16129032 91
7 0.19354839 93
8 0.22580645 95
9 0.25806452 97
10 0.29032258 105
11 0.32258065 109
12 0.35483871 110
13 0.35483871 110
14 0.35483871 110
15 0.45161290 113
16 0.48387097 123
17 0.48387097 123
18 0.54838710 150
19 0.54838710 150
20 0.61290323 175
21 0.61290323 175
22 0.61290323 175
23 0.70967742 180
24 0.70967742 180
25 0.70967742 180
26 0.80645161 205
27 0.83870968 215
28 0.87096774 230
29 0.90322581 245
30 0.90322581 245
31 0.96774194 264
32 1.00000000 335