取数据超过内存限制的问题-解决方案(sample,takeSample,filter)
遇到的问题
在处理数据过程中,遇到需要取(n)个数的问题,而当样本量过大的时候,就不能简单的take(n),这类问题一般有两种情况:
- 有序取 TopN
- 无序取 N
先来讨论无序取N的情况:
- sample函数
- sample(boolean, fraction,seed) : 按比例抽取
- 返回一个新的RDD
withReplacement:元素可以多次抽样(在抽样时替换)
- withReplacement=true,表示有放回的抽样
- withReplacement=false,表示无放回的抽样
fraction:期望样本的大小作为RDD大小的一部分, 当withReplacement=false时:选择每个元素的概率;分数一定是[0,1] ; 当withReplacement=true时:选择每个元素的期望次数; 分数必须大于等于0
seed:随机数生成器的种子
图 11中 的 每 个 方 框 是 一 个 RDD 分 区。 通 过 sample 函 数, 采 样 50% 的 数 据。V1、 V2、 U1、 U2、U3、U4 采样出数据 V1 和 U1、 U2 形成新的 RDD

图 sample 算子对 RDD 转换
- takeSample函数
- takeSample(boolean, sampleNum,seed) : 按固定数量抽取
- 返回一个Array[T]; 该方法仅在预期结果数组很小的情况下使用,因为所有数据都被加载到driver的内存中
- takeSample函数先是计算fraction,也就是采样比例,然后调用sample函数进行采样,并对采样后的数据进行collect(),最后调用take函数返回num个元素
withReplacement:元素可以多次抽样(在抽样时替换)
- withReplacement=true,表示有放回的抽样
- withReplacement=false,表示无放回的抽样
num:返回的样本的大小
seed:随机数生成器的种子

图 takeSample算子对RDD转换
再来看一下有序取 TopN的情况:
- filter函数
- 函数功能是对元素进行过滤,对每个元素应用 f 函 数,返回值为 true 的元素在RDD中保留,返回值为 false 的元素将被过滤掉。 内 部 实 现 相 当 于 生 成 FilteredRDD(this,sc.clean(f))
- 若是单列无法过滤,可以手动设置过滤位
- 有点遗憾的是无法准确的取固定量的数
图中每个方框代表一个 RDD 分区, T 可以是任意的类型。通过用户自定义的过滤函数 f,对每个数据项操作,将满足条件、返回结果为 true 的数据项保留。例如,过滤掉 V2 和 V3 保留了 V1,为区分命名为 V'1。

图 filter 算子对 RDD 转换
附:takeSample源码
def takeSample(
withReplacement: Boolean,
num: Int,
seed: Long = Utils.random.nextLong): Array[T] =
{
val numStDev = 10.0
if (num < 0) {
throw new IllegalArgumentException("Negative number of elements requested")
} else if (num == 0) {
return new Array[T](0)
}
val initialCount = this.count()
if (initialCount == 0) {
return new Array[T](0)
}
val maxSampleSize = Int.MaxValue - (numStDev * math.sqrt(Int.MaxValue)).toInt
if (num > maxSampleSize) {
throw new IllegalArgumentException("Cannot support a sample size > Int.MaxValue - " + s"$numStDev * math.sqrt(Int.MaxValue)")
}
val rand = new Random(seed)
if (!withReplacement && num >= initialCount) {
return Utils.randomizeInPlace(this.collect(), rand)
}
val fraction = SamplingUtils.computeFractionForSampleSize(num, initialCount, withReplacement)
var samples = this.sample(withReplacement, fraction, rand.nextInt()).collect()
// If the first sample didn't turn out large enough, keep trying to take samples;
// this shouldn't happen often because we use a big multiplier for the initial size
var numIters = 0
while (samples.length < num) {
logWarning(s"Needed to re-sample due to insufficient sample size. Repeat #$numIters")
samples = this.sample(withReplacement, fraction, rand.nextInt()).collect()
numIters += 1
}
Utils.randomizeInPlace(samples, rand).take(num)
}
取数据超过内存限制的问题-解决方案(sample,takeSample,filter)的更多相关文章
- PHP大量数据循环时内存耗尽问题的解决方案
最近在开发一个PHP程序时遇到了下面的错误:PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted错误信息显...分析: ...
- Java内存溢出的详细解决方案
本文介绍了Java内存溢出的详细解决方案.本文总结内存溢出主要有两种情况,而JVM经常调用垃圾回收器解决内存堆不足的问题,但是有时仍会有内存不足的错误.作者分析了JVM内存区域组成及JVM设置虚拟内存 ...
- C结构体中数据的内存对齐问题
转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...
- HBase指定大量列集合的场景下并发拉取数据时卡住的问题排查
最近遇到一例,HBase 指定大量列集合的场景下,并发拉取数据,应用卡住不响应的情形.记录一下. 问题背景 退款导出中,为了获取商品规格编码,需要从 HBase 表 T 里拉取对应的数据. T 对商品 ...
- MongoDBDao 工具类(包含分页取数据)
mongdb工具类 package e16wifi.statistic.com.mongodb; import java.util.ArrayList; import java.util.List; ...
- 使用程序获取整型数据和浮点型数据在内存中的表示---gyy整理
使用程序获取整型数据和浮点型数据在内存中的表示. C++中整型(int).短整型(short int).单精度浮点数(float).双精度浮点数(double)在内存中所占字节数不同,因此取值范围也不 ...
- Android(java)学习笔记182:保存数据到SD卡 (附加:保存数据到内存)
1. 如果我们要想读写数据到SD卡中,首先必须知道SD的路径: File file = new File(Environment.getExternalStorageDirectory()," ...
- Stack的三种含义(数据超过栈的大小,就发生stack overflow)
非常典型的基础知识,转自http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈& ...
- windows环境下nutch2.x 在eclipse中实现抓取数据存进mysql详细步骤
nutch2.x 在eclipse中实现抓取数据存进mysql步骤 最近在研究nutch,花了几天时间,也遇到很多问题,最终结果还是成功了,在此记录,并给其他有兴趣的人提供参考,共同进步. 对nutc ...
随机推荐
- jquerymobile tap事件被触发两次
首先介绍一下这个问题出现的背景:我在写网站时想要一套代码兼容手机端和pc端,所以用了jquery和jquery mobile,点击事件用的jquerymobile tap事件,但是在移动端测试时出现点 ...
- go常量的定义和枚举类型
const a,b int = 1,2 const a,b = 1,2 const ( a = "hello" b,c =3,4 ) 常量数值可作为各种类型使用 枚举类型的 ...
- Wireshark远程抓包
1.被监控主机上,在安装目录下点击rpcapd.exe,运行server服务,并关闭防火墙 2.监控机器上,Capture Options,点击Manage Interfaces,弹出如下对话框 选择 ...
- js中event.preventDefault()和 event.stopPropagation( ) 方法详解
event.preventDefault() 1.首先event.preventDefault()是通知浏览器不要执行与事件关联的默认动作,例如: 这里a标签的默认事件是跳转,这里我们告诉浏览器取消 ...
- vue:概要
一.环境 #安装nodejs-官网安装包配置环境变量 node -v #安装webpack npm install webpack -g #安装vue-cli npm install vue-cli ...
- sparkStreaming 读kafka的数据
目标:sparkStreaming每2s中读取一次kafka中的数据,进行单词计数. topic:topic1 broker list:192.168.1.126:9092,192.168.1.127 ...
- 学生管理系统——数据库、java基础
1.项目分层 view层:视图层 controller层:控制层 service层:业务层 dao层:数据库访问层 domain:实体包 tools:工具类 2.jar包 3.配置文件 4.程序设计 ...
- Windows 2012R2安装KB2919355失败
安装KB2919355时候失败,提示此更新不适用于此计算机. 需要首先安装KB2919442.
- 模拟I2C协议学习点滴之复习三极管、场效应管
晶体三极管分为NPN和PNP型两种结构形式,除了电源极性的不同工作原理是大致相同的.对于NPN管,它是由2块N型半导体夹着一块P型半导体所组成的,发射区与基区之间形成的PN结称为发射结,而集电区与基区 ...
- 洛谷P1016 旅行家的预算 题解
主要就是注意一下各个变量的类型别弄混了 https://www.luogu.org/problem/P1016 #include<cstdio> using namespace std; ...