Spark SQL dropDuplicates
spark sql 数据去重
在对spark sql 中的dataframe数据表去除重复数据的时候可以使用dropDuplicates()方法
dropDuplicates()有4个重载方法
- 第一个
def dropDuplicates(): Dataset[T] = dropDuplicates(this.columns)
这个方法,不需要传入任何的参数,默认根据所有列进行去重,然后按数据行的顺序保留每行数据出现的第一条。
/**
* Returns a new Dataset that contains only the unique rows from this Dataset.
* This is an alias for `distinct`.
*
* For a static batch [[Dataset]], it just drops duplicate rows. For a streaming [[Dataset]], it
* will keep all data across triggers as intermediate state to drop duplicates rows. You can use
* [[withWatermark]] to limit how late the duplicate data can be and system will accordingly limit
* the state. In addition, too late data older than watermark will be dropped to avoid any
* possibility of duplicates.
*
* @group typedrel
* @since 2.0.0
*/
def dropDuplicates(): Dataset[T] = dropDuplicates(this.columns)
- 第二个
def dropDuplicates(colNames: Seq[String])
传入的参数是一个序列。你可以在序列中指定你要根据哪些列的重复元素对数据表进行去重,然后也是返回每一行数据出现的第一条
/**
* (Scala-specific) Returns a new Dataset with duplicate rows removed, considering only
* the subset of columns.
*
* For a static batch [[Dataset]], it just drops duplicate rows. For a streaming [[Dataset]], it
* will keep all data across triggers as intermediate state to drop duplicates rows. You can use
* [[withWatermark]] to limit how late the duplicate data can be and system will accordingly limit
* the state. In addition, too late data older than watermark will be dropped to avoid any
* possibility of duplicates.
*
* @group typedrel
* @since 2.0.0
*/
def dropDuplicates(colNames: Seq[String]): Dataset[T] = withTypedPlan {
val resolver = sparkSession.sessionState.analyzer.resolver
val allColumns = queryExecution.analyzed.output
val groupCols = colNames.toSet.toSeq.flatMap { (colName: String) =>
// It is possibly there are more than one columns with the same name,
// so we call filter instead of find.
val cols = allColumns.filter(col => resolver(col.name, colName))
if (cols.isEmpty) {
throw new AnalysisException(
s"""Cannot resolve column name "$colName" among (${schema.fieldNames.mkString(", ")})""")
}
cols
}
Deduplicate(groupCols, planWithBarrier)
}
- 第三个
def dropDuplicates(colNames: Array[String])
传入的参数是一个数组,然后方法会把数组转换为序列然后再调用第二个方法。
/**
* Returns a new Dataset with duplicate rows removed, considering only
* the subset of columns.
*
* For a static batch [[Dataset]], it just drops duplicate rows. For a streaming [[Dataset]], it
* will keep all data across triggers as intermediate state to drop duplicates rows. You can use
* [[withWatermark]] to limit how late the duplicate data can be and system will accordingly limit
* the state. In addition, too late data older than watermark will be dropped to avoid any
* possibility of duplicates.
*
* @group typedrel
* @since 2.0.0
*/
def dropDuplicates(colNames: Array[String]): Dataset[T] = dropDuplicates(colNames.toSeq)
- 第四个
def dropDuplicates(col1: String, cols: String*)
传入的参数为字符串,在方法体内会把你传入的字符串组合成一个序列再调用第二个方法。
/**
* Returns a new [[Dataset]] with duplicate rows removed, considering only
* the subset of columns.
*
* For a static batch [[Dataset]], it just drops duplicate rows. For a streaming [[Dataset]], it
* will keep all data across triggers as intermediate state to drop duplicates rows. You can use
* [[withWatermark]] to limit how late the duplicate data can be and system will accordingly limit
* the state. In addition, too late data older than watermark will be dropped to avoid any
* possibility of duplicates.
*
* @group typedrel
* @since 2.0.0
*/
@scala.annotation.varargs
def dropDuplicates(col1: String, cols: String*): Dataset[T] = {
val colNames: Seq[String] = col1 +: cols
dropDuplicates(colNames)
}
第三和第四个本质上还是调用了第二个方法,所以我们在使用的时候如果需要根据指定的列进行数据去重,可以直接传入一个Seq。
第一个方法默认根据所有列去重,实际上也是调用了第二个方法,然后传入参数this.columns,即所有的列组成的Seq。
所以各位想深究dropDuplicate()去重的核心代码,只需要研究第二个去重方法即可。等我有时间我也会把去重的核心源码讲解继续补充。
dropDuplicates()的坑!
在使用dropDuplicates() 在去重的时候,我发现有时候还是会出现重复数据的情况。
我分析了一下还出现重复数据的原因:
- 数据存在多个excuter中
因为spark是分布式计算的,数据在计算的时候会分布在不同的excutor上,使用dropDuplicate去重的时候,可能只是一个excutor内的数据进行了去重,别的excutor上可能还会有重复的数据。
- 数据是存放在不同分区的,
因为spark是分布式计算的,数据在计算的时候会分散在不同的分区中,使用dropDuplicate去重的时候,不同的区分可能还会存在相同的数据。
我试了只启动一个excutor多分区的情况下进行计算,没有出现重复的数据,然后多个excutor将数据先合并到一个分区在去重还是有重复的数据。所以觉得可能是第一种猜测的情况比较大,但是如果只使用一个excutor就失去了分布式计算的意义和优势,所以还是得想想其它办法。
各位有什么好的解决办法也可以在评论区交流!
Spark SQL dropDuplicates的更多相关文章
- Spark2.x学习笔记:Spark SQL程序设计
1.RDD的局限性 RDD仅表示数据集,RDD没有元数据,也就是说没有字段语义定义. RDD需要用户自己优化程序,对程序员要求较高. 从不同数据源读取数据相对困难. 合并多个数据源中的数据也较困难. ...
- Spark SQL 之 Data Sources
#Spark SQL 之 Data Sources 转载请注明出处:http://www.cnblogs.com/BYRans/ 数据源(Data Source) Spark SQL的DataFram ...
- Spark SQL 之 DataFrame
Spark SQL 之 DataFrame 转载请注明出处:http://www.cnblogs.com/BYRans/ 概述(Overview) Spark SQL是Spark的一个组件,用于结构化 ...
- 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL
周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...
- Spark 官方文档(5)——Spark SQL,DataFrames和Datasets 指南
Spark版本:1.6.2 概览 Spark SQL用于处理结构化数据,与Spark RDD API不同,它提供更多关于数据结构信息和计算任务运行信息的接口,Spark SQL内部使用这些额外的信息完 ...
- Spark SQL Example
Spark SQL Example This example demonstrates how to use sqlContext.sql to create and load a table ...
- 通过Spark SQL关联查询两个HDFS上的文件操作
order_created.txt 订单编号 订单创建时间 -- :: -- :: -- :: -- :: -- :: order_picked.txt 订单编号 订单提取时间 -- :: ...
- Spark SQL 之 Migration Guide
Spark SQL 之 Migration Guide 支持的Hive功能 转载请注明出处:http://www.cnblogs.com/BYRans/ Migration Guide 与Hive的兼 ...
- Spark SQL 官方文档-中文翻译
Spark SQL 官方文档-中文翻译 Spark版本:Spark 1.5.2 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 Data ...
随机推荐
- JVM详解之:HotSpot VM中的Intrinsic methods
目录 简介 什么是Intrinsic Methods 内置方法的特点 多样性 兼容性 java语义的扩展 Hotspot VM中的内置方法 intrinsic方法和内联方法 intrinsic方法的实 ...
- Upload 上传 el-upload 上传配置请求头为Content-Type: "multipart/form-data"
api接口处添加属性 (标红处) // 校验台账 export const checkEquiment = (data) => { return axios({ url: '/job/equip ...
- HTML <body> 标签
HTML <body> 标签 实例 一个简单的 HTML 文档,包含尽可能少的必需的标签: <!DOCTYPE html> <html> <head> ...
- PHP import_request_variables() 函数
import_request_variables() 函数将 GET/POST/Cookie 变量导入到全局作用域中.该函数在最新版本的 PHP 中已经不支持.高佣联盟 www.cgewang.com ...
- Pintech品致—示波器探头技术标准倡导者
Pintech品致是仪器仪表的品牌,全球示波器探头第一品牌,示波器探头技术标准倡导者:“两点浮动”电压测试创始人:世界知名品牌,泰克(Tektronix),罗德与施瓦茨R&S,是德(Keys ...
- 每日一道 LeetCode (5):最长公共前缀
前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...
- requests入门实践01_下载2560*1080的电脑壁纸
新版本移步:https://www.cnblogs.com/zy7y/p/13376228.html 附上代码 # !usr/bin/env python # -*- coding:utf-8 -*- ...
- JAVA的基本程序设计结构<上>
一个简单的Java应用程序 public class FirstSample { public static void main(String[] args) { System.out.println ...
- three.js 着色器材质之变量(三)
这篇郭先生在练习一下着色器变量,在度娘上面或者官网上经常看到类似水波一样的效果,这篇就试着做一个这样的效果,顺便巩固一下顶点着色器和片元着色器,毕竟多多练习才能更好地掌握.效果如下图,在线案例请点击博 ...
- go微服务系列(一) go micro入门
1. 什么是go micro 1.1 go micro作用 1.2 go micro架构组成 2. go micro入门 3. 结合consul进行服务注册/发现 3.1 consul的安装 3.2 ...