Spark源码-sample计算流程分析

银行TB级客户行为分析:Spark+Scala实战架构与调优 客户行为分析是金融数据工程的核心能力,其本质是将多源异构交易、账户与日志数据,转化为可解释、可行动的业务洞察。该能力依赖稳定可控的分布式计算框架与强类型、高表达力的编程语言协同实现。Spark凭借DAG调度、血缘追踪与批流一体能力,成为银行T+1级客户分群与360视图构建的事实标准;Scala则以不可变集合、模式匹配和Case Class等特性,天然契合银行业务规则严谨性与数据治理刚性要求。本文聚焦银行真实生产场景,详解如何基于Spark SQL与Scala API完成数据清洗、BRFM分群建模、渠道路径还 阅读详情

1.参数说明

    Sample构造函数有三个参数,每个参数的含义如下:

    withReplacement:元素可以多次抽样(有放回的抽样)

    fraction:期望样本的大小作为RDD大小的一部分, 当withReplacement=false时:选择每个元素的概率;分数一定是[0,1] ; 当    withReplacement=true时:选择每个元素的期望次数; 分数必须大于等于0。

    seed:随机数生成器的种子

2.源码流程分析

    往下找sample的源码,可以看到调用了RDD的sample方法:

def sample(
    withReplacement: Boolean,
    fraction: Double,
    seed: Long = Utils.random.nextLong): RDD[T] = {
  require(fraction >= 0,
    s"Fraction must be nonnegative, but got ${fraction}")

  withScope {
    require(fraction >= 0.0, "Negative fraction value: " + fraction)
    if (withReplacement) {
      new PartitionwiseSampledRDD[T, T](this, new PoissonSampler[T](fraction), true, seed)
    } else {
      new PartitionwiseSampledRDD[T, T](this, new BernoulliSampler[T](fraction), true, seed)
    }
  }
}

    方法前面都是对fraction合理性的判断,主要还是要看if和else中。都是返回了PartitionwiseSampleRDD对象,并且其构造方法传入了PoissonSampler和BernoulliSampler对象。当withReplacement=false时,是选择每个元素的概率,所以我们先看BernoulliSampler。

2.BernoulliSampler(伯努利分布)

 

class BernoulliSampler[T: ClassTag](fraction: Double) extends RandomSampler[T, T] {

  /** epsilon slop to avoid failure from floating point jitter */
  require(
    fraction >= (0.0 - RandomSampler.roundingEpsilon)
      && fraction <= (1.0 + RandomSampler.roundingEpsilon),
    s"Sampling fraction ($fraction) must be on interval [0, 1]")

  private val rng: Random = RandomSampler.newDefaultRNG

  override def setSeed(seed: Long): Unit = rng.setSeed(seed)

  private lazy val gapSampling: GapSampling =
    new GapSampling(fraction, rng, RandomSampler.rngEpsilon)

  override def sample(): Int = {
    if (fraction <= 0.0) {
      0
    } else if (fraction >= 1.0) {
      1
    } else if (fraction <= RandomSampler.defaultMaxGapSamplingFraction) {
      gapSampling.sample()
    } else {
      if (rng.nextDouble() <= fraction) {
        1
      } else {
        0
      }
    }
  }

  override def clone: BernoulliSampler[T] = new BernoulliSampler[T](fraction)
}

    重点看BernoulliSampler类中的sample方法,到后面我们就可以看到在PartitionwiseSampleRDD对象中调用了该sample方法。如果fraction小于等于0.0,返回0,代表不被选择,大于等于1,就会被选择,当然这都是特殊情况,正常情况下都应该是(0,1)的。下面一个条件是fraction <= RandomSampler.defaultMaxGapSamplingFraction,后面的常量是0.4(不知道为啥要这样),后面调用了一个GapSampling对象的sample方法(裁员间隔采样的方法):

class GapSampling(
    f: Double,
    rng: Random = RandomSampler.newDefaultRNG,
    epsilon: Double = RandomSampler.rngEpsilon) extends Serializable {

  require(f > 0.0  &&  f < 1.0, s"Sampling fraction ($f) must reside on open interval (0, 1)")
  require(epsilon > 0.0, s"epsilon ($epsilon) must be > 0")

  private val lnq = math.log1p(-f)

  /** Return 1 if the next item should be sampled. Otherwise, return 0. */

/**如果下一个元素需要被选为例子的话,返回1,否则的话就返回0**/
  def sample(): Int = {
    if (countForDropping > 0) {
      countForDropping -= 1
      0
    } else {
      advance()
      1
    }
  }

  private var countForDropping: Int = 0

  /**
   * Decide the number of elements that won't be sampled,
   * according to geometric dist P(k) = (f)(1-f)^k.
   */
  private def advance(): Unit = {
    val u = math.max(rng.nextDouble(), epsilon)
    countForDropping = (math.log(u) / lnq).toInt
  }

  /** advance to first sample as part of object construction. */
  advance()
  // Attempting to invoke this closer to the top with other object initialization
  // was causing it to break in strange ways, so I'm invoking it last, which seems to
  // work reliably.
}

    我们看其sample函数,及时要返回0或1。其中用到了countForDropping和advance()方法。变量lng是对-fraction加一再取自然对数,advance方法中,先生成一个0-1的随机数,然后向下面是取了对数函数,可以简化为log以1-fraction为底,u的对数。根据注释的说法,这是个间隔采样,兴趣的可以研究一下,反正我是没怎么看明白。

    接着看BernoulliSampler的sample函数,跳过GapSampling对象的sample方法之后,后面的就很简单了,判断随机生成的0-1的数和fraction比较,如果小于fraction就返回1,否则返回0。

2.2 PoissonSampler(泊松分布)

class PoissonSampler[T](
    fraction: Double,
    useGapSamplingIfPossible: Boolean) extends RandomSampler[T, T] {

  def this(fraction: Double) = this(fraction, useGapSamplingIfPossible = true)

  /** Epsilon slop to avoid failure from floating point jitter. */
  require(
    fraction >= (0.0 - RandomSampler.roundingEpsilon),
    s"Sampling fraction ($fraction) must be >= 0")

  // PoissonDistribution throws an exception when fraction <= 0
  // If fraction is <= 0, Iterator.empty is used below, so we can use any placeholder value.
  private val rng = new PoissonDistribution(if (fraction > 0.0) fraction else 1.0)
  private val rngGap = RandomSampler.newDefaultRNG

  override def setSeed(seed: Long) {
    rng.reseedRandomGenerator(seed)
    rngGap.setSeed(seed)
  }

  private lazy val gapSamplingReplacement =
    new GapSamplingReplacement(fraction, rngGap, RandomSampler.rngEpsilon)

  override def sample(): Int = {
    if (fraction <= 0.0) {
      0
    } else if (useGapSamplingIfPossible &&
               fraction <= RandomSampler.defaultMaxGapSamplingFraction) {
      gapSamplingReplacement.sample()
    } else {
      rng.sample()
    }
  }

  override def sample(items: Iterator[T]): Iterator[T] = {
    if (fraction <= 0.0) {
      Iterator.empty
    } else {
      val useGapSampling = useGapSamplingIfPossible &&
        fraction <= RandomSampler.defaultMaxGapSamplingFraction

      items.flatMap { item =>
        val count = if (useGapSampling) gapSamplingReplacement.sample() else rng.sample()
        if (count == 0) Iterator.empty else Iterator.fill(count)(item)
      }
    }
  }

  override def clone: PoissonSampler[T] = new PoissonSampler[T](fraction, useGapSamplingIfPossible)
}

主要是用到了GapSamplingReplacement的sample和PoissonDistribution的sample,其方法如下:

GapSamplingReplacement.sample

class GapSamplingReplacement(
    val f: Double,
    val rng: Random = RandomSampler.newDefaultRNG,
    epsilon: Double = RandomSampler.rngEpsilon) extends Serializable {

  require(f > 0.0, s"Sampling fraction ($f) must be > 0")
  require(epsilon > 0.0, s"epsilon ($epsilon) must be > 0")

  protected val q = math.exp(-f)

  /**
   * Sample from Poisson distribution, conditioned such that the sampled value is >= 1.
   * This is an adaptation from the algorithm for Generating Poisson distributed random variables:
   * http://en.wikipedia.org/wiki/Poisson_distribution
   */
  protected def poissonGE1: Int = {
    // simulate that the standard poisson sampling
    // gave us at least one iteration, for a sample of >= 1
    var pp = q + ((1.0 - q) * rng.nextDouble())
    var r = 1

    // now continue with standard poisson sampling algorithm
    pp *= rng.nextDouble()
    while (pp > q) {
      r += 1
      pp *= rng.nextDouble()
    }
    r
  }
  private var countForDropping: Int = 0

  def sample(): Int = {
    if (countForDropping > 0) {
      countForDropping -= 1
      0
    } else {
      val r = poissonGE1
      advance()
      r
    }
  }

  /**
   * Skip elements with replication factor zero (i.e. elements that won't be sampled).
   * Samples 'k' from geometric distribution  P(k) = (1-q)(q)^k, where q = e^(-f), that is
   * q is the probability of Poisson(0; f)
   */
  private def advance(): Unit = {
    val u = math.max(rng.nextDouble(), epsilon)
    countForDropping = (math.log(u) / (-f)).toInt
  }

  /** advance to first sample as part of object construction. */
  advance()
  // Attempting to invoke this closer to the top with other object initialization
  // was causing it to break in strange ways, so I'm invoking it last, which seems to
  // work reliably.
}

这个是间隔采样。

PoissonDistribution.sample

public int sample() {
    return (int) FastMath.min(nextPoisson(mean), Integer.MAX_VALUE);
}

这个是伯努利采样。

Python数据分析实战:从Pandas数据处理到电商用户行为分析 数据分析是通过统计方法从海量数据中提取价值信息、支持决策的关键技术流程。其核心原理在于对原始数据进行系统性的清洗、转换与建模,以揭示潜在的模式与趋势。在工程实践中,Python凭借其简洁语法和强大的生态系统,已成为数据分析领域的主流工具,尤其适用于处理表格型数据和构建可视化报告。掌握Pandas进行数据清洗、聚合与合并,以及利用Matplotlib和Seaborn实现数据可视化,是每位数据分析师的基础技能。这些技术广泛应用于电商、金融、运营等多个场景,帮助从业者从用户行为数据中挖掘商业洞察,例如通过RFM模 阅读详情

相关推荐

Meta开源模型Muse系列实战:从权重部署到工程化应用指南

开源模型通过开放模型权重,实现了从黑盒API到透明、可定制化AI工具的转变,其核心在于权重文件包含了训练所得的全部参数,这为本地部署、微调和深度分析提供了可能。这一技术路径的价值在于赋予开发者对模型内部机制、数据流和计算环境的完全控制权,尤其适用于对数据隐私、成本可控性和定制化有高要求的场景。在工程实践中,开发者需掌握从环境配置、模型加载到提示工程和性能优化的全链路技能,例如针对Muse Glimmer这类代码生成模型,有效的提示词设计和量化技术是提升实用性的关键。随着Meta等厂商持续推动模型民主化,拥抱

迷彩风情 431

Spark之sample算子

在调用spark的sample算子时,对应的方法为: sample(withReplacement : scala.Boolean, fraction : scala.Double,seed scala.Long) sample算子是用来抽样用的,其有3个参数 withReplacement:表示抽出样本后是否在放回去,true表示会放回去,这也就意味着抽出的样本可能有重复 fractio...

qq_36561105的博客 5351

spark学习-20-Spark的sample理解

1.语法(java):JavaPairRDD<K,V> sample(boolean withReplacement, double fraction)JavaPairRDD<K,V> sample(boolean withReplacement, double fraction,

九师兄 1万+

spark sample

spark sample

qq_43192537的博客 783

关于spark的sample()算子参数详解

sample(withReplacement : scala.Boolean, fraction : scala.Double,seed scala.Long) sample算子时用来抽样用的,其有3个参数 withReplacement:表示抽出样本后是否在放回去,true表示会放回去,这也就意味着抽出的样本可能有重复 fraction :抽出多少,这是一个double类型的参数,0-1之...

lukabruce的博客 1万+

Spark 3.0 - 10.Ml 常用 Sample 采样方法

Spark 3.0 ML 常用采样方法。

BITDDD小栈 1171

Spark源码分析-takeSample源码分析

1.参数说明 withReplacement:是否是有放回的抽样,就是普通的抽样,我们都是抽过的数据就不能在抽样了,有放回抽样就是可以继续抽以前抽取过的。 num:数据抽样的个数 2.执行源码流程 执行流程主要是调用了RDD的takeSample方法,下面先贴上这个方法的代码: def takeSample( withReplacement: Boole...

things_use的博客 453

交通数据分析期末大作业实战:出租车GPS轨迹清洗、拥堵指数计算与可视化全流程

数据分析是交通工程与城市计算中的核心技能,而GPS轨迹数据正是理解城市交通运行状态的黄金素材。从原始出租车定位记录中提取有效信息,通常需要经过数据清洗、坐标转换、路网匹配等预处理环节,再通过平均速度、车流密度与拥堵指数等指标量化道路通行状况,最终借助可视化工具呈现时空规律。这类完整的数据分析流程不仅适用于课程设计与期末大作业,也是智能交通系统、出行服务与城市规划中常见的工程实践。本文以出租车GPS轨迹数据为例,梳理了从数据预处理到指标计算、可视化展示,再到实验报告撰写的全链路方法,并提供了开源工具链下的可复

weixin_34414650的博客 500

Spark源码分析之分区器的作用

spark分区

wayne_2015的博客 467

TSMaster MBD模块实战:如何用Simulink模型快速搭建汽车电子测试环境

本文实战演示了如何利用TSMaster的MBD模块,将Simulink模型快速部署为汽车电子自动化测试环境的核心。通过建立模型与TSMaster系统变量的实时数据通道,并利用数据仓库统一数据定义,工程师能无缝连接算法仿真与真实总线网络,显著提升从模型到HIL测试的验证效率。

php55的博客 207

STM32+HX711实战:5分钟搞定拉力传感器数据采集(附完整代码)

本文详细介绍了如何使用STM32微控制器和HX711模数转换器快速搭建高精度拉力测量系统。通过硬件连接指南、驱动实现代码和校准方法,帮助开发者在5分钟内完成拉力传感器数据采集,适用于工业自动化和消费电子等场景。

y7z8a9的博客 873

Spark 概述与编程模型

Mesos 与 yarn 类似 国内用 yarn 比较多 Tachyan 是分布式内存文件系统,并不仅支持 spark,也支持map-reduce hadoop2.3.0 的datanode 也支持 cache(重大改进) Spark Streaming Stream processing 是实时流处理 GraphX 是个图处理 MLbase 是个机器学习库 Shark SQL AP

Zephyr's Blog 1198

Wireshark实战解析IEC 61850 GOOSE报文:智能变电站通信调试指南

网络协议分析是理解现代工业通信系统的基础,其核心原理在于对数据包的捕获、解码与解析。在电力自动化领域,IEC 61850标准定义了智能变电站内设备间高效、可靠的通信框架,其中GOOSE(通用面向对象变电站事件)协议因其基于以太网多播和快速重传机制,成为保护跳闸、联锁等关键信号传输的基石,其技术价值在于实现了微秒级延迟的高可靠性通信。掌握GOOSE报文的分析能力,对于现场调试、故障定位及系统验证至关重要。本文聚焦于使用Wireshark这一网络分析工具,深入解析GOOSE报文结构,涵盖从以太网帧头、协议标识到

weixin_34401479的博客 374

Apache Spark分布式计算实战:从核心概念到集群部署与性能调优

分布式计算是处理海量数据的关键技术,其核心原理在于将大规模计算任务分解到多台机器上并行执行,从而突破单机性能瓶颈。这项技术的价值在于能够高效处理TB甚至PB级别的数据,显著提升数据处理速度与系统吞吐量。在工程实践中,分布式计算框架广泛应用于大数据分析、实时流处理、机器学习等场景。Apache Spark作为主流框架,以其内存计算和统一分析引擎著称,通过RDD、DataFrame等核心抽象实现高效数据处理。本文以Spark为例,深入解析其集群架构、资源调度机制,并提供从环境搭建、应用开发到生产部署的完整实战指

weixin_30788619的博客 532

Win10下Altera USB-Blaster驱动安装详解:禁用数字签名与排查指南

在嵌入式开发和FPGA调试过程中,驱动安装是工程师绕不开的环节,尤其是当操作系统对驱动签名有严格限制时,硬件往往无法被正常识别。数字签名是系统验证驱动程序来源和完整性的重要机制,Win10出于安全考虑,默认拒绝加载未经签名的驱动,这正是Altera USB-Blaster下载器在设备管理器中显示未知设备或黄色感叹号的根本原因。通过理解设备管理器的排查逻辑,掌握临时禁用驱动强制签名或开启测试模式的方法,配合正确的驱动文件路径选择与手动安装操作,即可解决Quartus无法检测到下载器的问题。这一流程同样适用于许

weixin_29164497的博客 245

智能车‘大脑’的诞生:揭秘电磁循迹代码背后的控制论与系统思维

本文深入探讨智能车电磁循迹系统的核心架构与控制原理,揭示了其作为精密闭环系统如何通过模块化设计、信号处理、PID控制算法及电机驱动实现自主导航。重点分析了电磁信号采集与处理流程框架,为开发者提供从理论到实践的全面指南。

arduino9maker的博客 531

Spark RDD sortBy vs sortByKey 对比:3个场景下的性能与适用性分析

本文深入对比了Spark RDD中sortBy与sortByKey两种排序算子的性能差异与适用场景。通过三个典型场景的基准测试和源码解析,揭示了sortByKey在键值对排序中的性能优势,以及sortBy在处理复杂对象和多字段排序时的灵活性。文章还提供了优化技巧和最佳实践,帮助开发者在Spark数据处理中选择合适的排序方法。

weixin_34277853的博客 419

Ubuntu 上 1Panel 的安装与高效运维实践

本文详细介绍了在Ubuntu系统上安装和高效运维1Panel面板的完整实践指南。内容涵盖了一键安装、Docker容器可视化部署、计划任务自动化以及网站数据库管理等核心功能,并提供了安全加固、资源监控与数据备份等进阶技巧,旨在帮助用户快速搭建并管理一个强大易用的服务器环境。

weixin_29210759的博客 143

基于Django的租房市场数据分析系统设计与实现

数据分析和推荐系统是现代互联网应用的核心技术组件。通过ETL流程处理原始数据,结合协同过滤等算法构建推荐模型,能够有效解决信息过载问题。Python生态中的Django框架以其完善的ORM系统和Admin后台,大幅提升了Web应用的开发效率。在实际工程中,这类系统通常采用模块化设计,整合大数据处理、机器学习算法和数据可视化技术。以租房市场为例,基于Django开发的房源数据分析系统,既能实现价格预测、智能推荐等核心功能,又便于进行毕业设计或商业部署。系统采用PostgreSQL存储结构化数据,配合Redis

weixin_34378969的博客 306

Linux下开机异常(fsck exited with status code 4)

Linux下开机异常事情是这样的,本来我呢跑着程序听着歌,结果忽然就死机了,我只能强制关机,再次打开系统的时候,就提示这样fsck from util-linux 2.26.2 /dev/sda10 contains a file system with errors, check forced. /dev/sda10: Inodes that were part of a corrupted pr

芳草碧连天 2万+

46、大数据助力SDN优化流量管理与控制器

本文探讨了大数据在软件定义网络(SDN)中的应用,重点分析了如何利用大数据技术优化SDN控制器的可扩展性和弹性。通过介绍SDN控制器的核心功能及其面临的挑战,提出了集中式、分布式、混合式和分层式控制器放置策略,并结合大数据分析系统架构与技术,详细阐述了在控制器放置优化、流聚合和备份路径识别等场景中的实际应用。文章还给出了大数据分析在SDN控制器优化中的操作流程与优势,展望了未来结合人工智能与物联网的发展方向,强调了数据安全与算法效率的重要性。

xx56789的博客 86

美团大数据开发校招面经:从Spark调优到数仓建模的实战复盘

大数据开发的核心是构建稳定高效的数据管道,涵盖采集、存储、计算与建模全链路。Spark与Flink作为批流计算的主流引擎,其作业调度、Shuffle机制及Checkpoint原理,直接决定任务性能与可靠性;而Kafka削峰填谷、数据仓库分层建模及数据倾斜治理,则是海量数据场景下必须掌握的工程能力。这些技术原理不仅支撑着美团外卖、到店等业务每日千亿级日志的实时分析与离线统计,也是校招面试中考察候选人实战思维的高频考点。本文以2024届美团大数据开发工程师真实面经为基础,梳理从笔试算法到技术面追问的完整准备路径

weixin_34199405的博客 376

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

cppcheck 的 mismatchAllocDealloc 检查详解:如何精准发现 C/C++ 中分配与释放不匹配的未定义行为

mismatchAllocDealloc 是 cppcheck 静态分析器中针对"分配函数与释放函数不匹配"问题的高置信度错误检查项(Error 级别,归入 Undefined Behaviour 分类)。它专门捕获诸如 `new[]` 用 `delete` 释放、`fopen` 用 `free` 释放这类会导致堆损坏、文件描述符泄漏或数据未刷盘的严重缺陷。本文将结合 [checkmemoryle

gitblog_02070的博客 469

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Python通达信数据读取终极指南:Mootdx解放你的金融数据分析生产力

在金融量化分析的世界里,你是否曾经为获取高质量的通达信数据而烦恼?面对复杂的专有格式、繁琐的导出步骤和昂贵的数据接口,Python开发者常常感到束手无策。今天,我要向你介绍一个革命性的工具——Mootdx,它将彻底改变你处理通达信数据的方式,让你轻松实现金融数据的Python化分析。Mootdx是一个专门为Python开发者设计的通达信数据读取工具,通过简单的封装让你能够直接读取通达信本地数据文件

gitblog_00458的博客 1047

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

多维聚合实战:滚动计算、层级展开与业务逻辑内嵌

多维聚合是数据分析的核心能力,本质是构建可解释、可执行的数据立方体,而非简单分组求和。其原理涉及维度建模、窗口控制与业务语义嵌入,技术价值在于支撑风控决策、监管报送与实时经营分析。关键挑战包括维度爆炸导致的内存失控、滚动窗口的时间对齐偏差、层级展开中的缺失组合误读,以及自定义函数不可审计等工程风险。典型应用场景涵盖银行反欺诈指标计算、商户风险分层、YTD累积统计等高可靠性要求任务。本文聚焦生产级实践,深入解析滚动计算与层级展开如何承载真实业务逻辑内嵌。

weixin_33676492的博客 351

pandas多维聚合实战:金融级数据分析的7大核心模式

多维聚合是OLAP分析的基础能力,指在多个业务维度(如区域、产品、时间)上对度量指标进行分组计算与结构化汇总。其核心原理在于将原始数据按维度组合切片,再应用统计规则提炼特征,从而支撑动态钻取、交叉分析与趋势洞察。技术价值体现在提升分析可复用性、保障计算可审计性,并为BI看板、风控模型和经营决策提供稳定数据底座。典型应用场景包括银行客户分群、电商销售透视、SaaS用户行为分析等,尤其在需处理滚动窗口、自定义业务逻辑、缺失值语义填充及MultiIndex列名扁平化的复杂需求中,pandas的groupby、un

dihuangxiu8828的博客 375
上一篇: Spark计算流程分析(map-reduce)过程
下一篇: Spark源码分析-takeSample源码分析
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值