Spark 用代码实现求分位数Percentile(Quentile)的方法
参考下文得到的启发
https://stackoverflow.com/questions/28805602/how-to-compute-percentiles-in-apache-spark
简单说明下分位数的定义
Scala求分位数的方法:
/*** compute percentile from an unsorted Spark RDD* @param data: input data set of Long integers* @param tile: percentile to compute (eg. 85 percentile)* @return value of input data at the specified percentile*/def computePercentile(data: RDD[Long], tile: Double): Double = {// NIST method; data to be sorted in ascending orderval r = data.sortBy(x => x)val c = r.count()if (c == 1) r.first()else {val n = (tile / 100d) * (c + 1d)val k = math.floor(n).toLongval d = n - kif (k <= 0) r.first()else {val index = r.zipWithIndex().map(_.swap)val last = cif (k >= c) {index.lookup(last - 1).head} else {index.lookup(k - 1).head + d * (index.lookup(k).head - index.lookup(k - 1).head)}}}}
请注意,事例代码中求分位数的方式,是求的加权分位数,关键代码如下:
在实际工作中,可以自行改写(算术平均值)。
===================================
下面的重点来了,如何求出Spark dataframe中某一列的分位数?
思路: DataFrame得出某一列,转为Rdd,调用刚才写的函数即可。
在写此贴之前,本人曾用sparksql的方式实现了分位数的功能,但因为执行效率不高,在这里就不展示此种方法了。
下面我列出我认为比较关键的代码,仅供参考:
import org.apache.spark.sql.Row
import com.google.gson.Gson
import org.apache.spark.sql.Dataset
import org.apache.ibatis.jdbc.SQL
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.functions._//initDF是一个DataFrame
//求出initDF的price列,并转为Rdd
//brand是品牌名称,需要自己去定义,或者从某个列表中获取
var price = initDF.select("price").filter($"brand_name" === brand).rdd.map(x => x(0).toString().toDouble)//compute Percentile var q1 = computePercentile(price, 25)var q2 = computePercentile(price, 50)var q3 = computePercentile(price, 75)//computePercentile方法,我做了些许改写,求的是算术平均分位数 def computePercentile(data: RDD[Double], tile: Double): Double = {// NIST method; data to be sorted in ascending orderval r = data.sortBy(x => x)val c = r.count()if (c < 4) {0}else {val n = (tile / 100d) * cval k = math.floor(n).toLongval d = math.ceil(n).toLongval index = r.zipWithIndex().map(_.swap)val last = cif (k >= c) {index.lookup(last - 1).head} else {(index.lookup(k - 1).head + index.lookup(d-1).head)/2}}}
得到你想要的分位数后,你就可以和其他变量组合在一起,愉快的玩耍,生成任意你想要的数据格式(DataFrame,json等等)
Spark 用代码实现求分位数Percentile(Quentile)的方法相关推荐
- 最大流matlab代码,matlab求最大流问题
如下图,我的代码只能求指定两点的最大流,例如V1到V6,列出邻接矩阵C=[0 1 0 1 0 0,1 0 1 0 1 0,0 1 0 1 0 1,1 0 1 0 1 0,0 1 0 1 0 1,0 0 ...
- 求读取CATIA标注的方法或者样例代码 Annotion
求读取CATIA标注的方法或者样例代码 Annotion 文韬777 2018-01-09 19:34:53 1572 收藏 6 文章来源 : http://bbs.csdn.net/topics ...
- 分位数回归的实现方法
目录 分位数回归简介 实现方法 参考文献 分位数回归简介 简介参照可参照参考文献[1].如下图,散点图代表我们所需分析数据,若用简单的参数方程拟合,即只利用期望值,会损失很多数据特征.因此分位数回归就 ...
- 求 LCA 的三种方法
(YYL: LCA 有三种求法, 你们都知道么?) (众神犇: 这哪里来的傻叉...) 1. 树上倍增 对于求 LCA, 最朴素的方法是"让两个点一起往上爬, 直到相遇", &qu ...
- java语言中如何表示素数,使用Java语言求素数的几个方法
使用Java语言求素数的几个方法 今天找了一篇"面试50题"的文档,第一题是求fibonacci数列,使用递归很容易就实现了,没什么难度. 第二题是输出101~200之间的素数,没 ...
- JAVA 计算圆的面积和周长: 创建一个圆Circle类。为该类提供一个变量r表示半径,一个常量PI表示圆周率; * 同时为该类提供两个方法:方法一用于求圆的面积,方法二用于求圆的周长;
插一句嘴,现在扎扎实实地把这些基础地敲一遍,理解了,可能还是会忘记.但是你最后学习的是做题的思路,而不是单纯的记代码.代码忘了再回过头来看一遍就好了,思路是别人偷不走的.[2022-9] * 思路 ...
- 【牛顿迭代逼近】求根号2的快速方法
如果要求根号2,比较快的方法有:1)二分法:2)牛顿迭代逼近法 二分法不多说了,很简单.下面介绍牛顿迭代逼近法. 原理:X(n+1) = ( X(n) + P/X(n) ) / 2 (P为待 ...
- Spark SQL DataFrame新增一列的四种方法
Spark SQL DataFrame新增一列的四种方法 方法一:利用createDataFrame方法,新增列的过程包含在构建rdd和schema中 方法二:利用withColumn方法,新增列的过 ...
- python求列表list平均值的方法
python求列表list平均值的步骤 python内置了两个函数,sum()和len()方法,其中sum()可以用于求取列表的元素和,len()函数可以用于求取列表list元素的个数,由此,利用py ...
最新文章
- Tensorflow的高级封装
- 10个必会的 PyCharm 技巧,附高清大图
- linux c变量命名规则,C语言中变量名及函数名的命名规则与驼峰命名法
- 膨润土和cmc和php,膨润土矿钻探用低固相泥浆的配方选择与生产试验
- loadrunner11录制不成功解决方法
- Servlet的执行原理和生命周期
- 制作开心网页游戏 HTML+CSS静态网页
- 【VScode】ubuntu系统的 VScode 调不出中文输入法
- Android 最常用的设计模式二 安卓源码分析——组合模式(component)
- 查询中国天气网api需要用到的城市代码
- springboot配置redis(单节点)
- 【Running latest Apollo with SVL Simulator 使用 SVL 模拟器运行最新的 Apollo】
- Unity5 Standard自发光材质无效解决方法
- 预防ddos攻击常用方法有哪些
- 天猫精灵连接蓝牙摸索1 关于阿里巴巴蓝牙MESH芯片TG7100B LINUX 开发环境塔建图文说明
- Google开源的Deep-Learning项目word2vec处理中文
- 据说是新浪乐居的面试题及我的答案
- java作用域范围_比较java中四个域的作用域范围大小
- 高并发和大流量解决方案
- SQL学习之check约束