如何使用分布式方法,IPython和Spark找到 RDD
整数的中位数? RDD
大约有700,000个元素,因此太大而无法收集并找到中位数 .
这个问题与这个问题类似 . 但是,问题的答案是使用Scala,我不知道 .
How can I calculate exact median with Apache Spark?
使用Scala答案的思考,我试图在Python中编写类似的答案 .
我知道我首先要排序 RDD
. 我不知道怎么 . 我看到 sortBy
(按给定的 keyfunc
对此RDD进行排序)和 sortByKey
(对此 RDD
进行排序,假设它由(键,值)对组成 . )方法 . 我认为两者都使用键值,而我的 RDD
只有整数元素 .
-
首先,我在考虑做
myrdd.sortBy(lambda x: x)
? -
接下来我会找到rdd的长度(
rdd.count()
) . -
最后,我想在rdd的中心找到元素或2个元素 . 我也需要这个方法的帮助 .
编辑:
我有个主意 . 也许我可以索引我的 RDD
然后key = index和value = element . 然后我可以尝试按 Value 排序?我不知道这是否可行,因为只有 sortByKey
方法 .
4 回答
Spark 2.0:
您可以使用实现Greenwald-Khanna algorithm的
approxQuantile
方法:Python :
Scala :
其中最后一个参数是相对误差 . 数字越低,结果越准确,计算成本也越高 .
从Spark 2.2(SPARK-14352)开始,它支持对多列进行估算:
和
Spark <2.0
Python
正如我在评论中提到的那样,很可能不值得大惊小怪 . 如果数据在您的情况下相对较小,那么只需在本地收集和计算中位数:
我几年前的电脑需要大约0.01秒,内存大约5.5MB .
如果数据量大得多,则排序将是一个限制因素,因此,不是获得精确值,而是在本地进行采样,收集和计算可能更好 . 但是,如果你真的想要使用Spark这样的东西应该做的伎俩(如果我没有弄乱任何东西):
还有一些测试:
最后定义中位数:
到目前为止一切都很好,但在本地模式下需要4.66秒而没有任何网络通信 . 可能有办法改善这一点,但为什么甚至打扰?
Language independent (Hive UDAF):
如果您使用
HiveContext
,您也可以使用Hive UDAF . 具有整数值:持续的 Value 观:
在
percentile_approx
中,您可以传递一个额外的参数,该参数确定要使用的记录数 .如果您只想要RDD方法并且不想转移到DF,请添加解决方案 . 这个片段可以让你获得双倍RDD的百分位数 .
如果您输入百分位数为50,则应获得所需的中位数 . 如果有任何角落案例没有考虑,请告诉我 .
这是我使用窗口函数(使用pyspark 2.2.0)时使用的方法 .
然后调用addMedian方法来计算col2的中位数:
最后,如果需要,您可以分组 .
我编写了一个函数,它将数据帧作为输入,并返回一个数据帧,其中间值作为分区输出,order_col是我们想要计算中间值的列,我们想要计算中位数的中位数: