实战-SparkSql
SparkSql的实战
一 铭
公众号:大数据架构师修行之路
展开
-
如何高效的进行空值的填充
有时我们需要对spark的dataframe的空值列进行填充,本文介绍几种可以用于填充空值的方法。全域填充通过fillna可以对dataframe的每个列的空值进行填充,下面是一个列子,用来填充df5的所有空值。$ df5.na.fill(False).show()+----+-------+-----+| age| name| spy|+----+-------+-----+| 10| Alice|false|| 5| Bob|false||null|Mallory|原创 2021-01-14 16:30:46 · 2118 阅读 · 0 评论 -
Spark sql实战--如何比较两个dataframe是否相等
说明Spark并没有提供比较两个dataframe是否相等的函数,所以,需要通过现有的函数来完成任务。但不同方式的性能有很大不同。这里提供4种方式来比较两个Dataframe是否相等,可以根据不同的场景来选择使用。实现方案对于小的dataframe,可以直接collect回来,然后比较。(1)先检查表结构是否相等;(2)确保df1,df2,df3没有重复行 ,使用intersect,并查看其count数是否和df的count数相等使用subtract函数可以通过subtract函数原创 2021-01-05 14:16:24 · 4760 阅读 · 0 评论 -
如何遍历处理dataframe的每一行?
有时我们会对dataframe的每一行进行遍历处理,有两种方式可以采用:使用map函数def customFunction(row): return (row.name, row.age, row.city)sample2 = sample.rdd.map(customFunction)自定义一个处理函数,并通过rdd的map函数来处理dataframe的每一行数据。使用collect()函数若数据量比较小,可以把数据收集到driver本地,然后再用常规的方法来遍历数据。for row原创 2021-01-04 20:51:50 · 9844 阅读 · 1 评论 -
Spark Sql实战: 如何获取dataframe的前n行和后n行?
数据准备import org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.types._import org.apache.spark.sql.functions._case class Salary(depName: String, empNo: Long, name: String, salary: Long, hobby: Seq[String])val df = Seq( Salary("sa原创 2020-11-03 12:28:23 · 13633 阅读 · 0 评论 -
Spark Sql窗口函数的使用(2)
接上一节,本文继续介绍窗口函数的使用。但会介绍如何基于窗口函数的范围函数来进行计算。准备工作准备依赖库import org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.types._import org.apache.spark.sql.functions._准备数据case class Salary(depName: String, empNo: Long, name: String, sa原创 2020-10-31 11:55:54 · 1040 阅读 · 0 评论 -
如何减少RDD持久化时的文件数量
问题的提出有时候,通过saveAsTextFile把RDD的数据 保存到HDFS中时会产生很多文件,文件的个数由分区数决定。这在很多时候这不是我们想要的结果。因为若分区数量太大,会产生大量的小文件,所以,我们希望文件数量可控,有时希望把RDD的数据保存到一个文件中。问题分析RDD保存时的文件数量是由RDD的分区数量决定的。可以通过以下代码来查看分区数:rdd.partitions.length若我们想要控制文件数量,其实就是要改变分区数量。改变分区数量的方式有很多种,比如:重分区,自己控制每个原创 2020-10-29 08:50:49 · 463 阅读 · 0 评论 -
Spark Sql窗口函数Window的使用(1)
窗口函数的使用(1)窗口是非常重要的统计工具,很多数据库都支持窗口函数。Spark从1.4开始支持窗口(window)函数。它主要有以下一些特点:先对在一组数据行上进行操作,这组数据被称为Frame。一个Frame对应当前处理的行通过聚合/窗口函数为每行返回一个新值可以使用SQL语法或DataFrame API。准备工作准备依赖库import org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.typ原创 2020-10-28 07:12:00 · 2809 阅读 · 0 评论 -
如何打印RDD每个分区的数据,并输出分区号?
问题的提出有时候我们在调试数据处理任务时,希望能够打印出一每个分区的数据,并要打印出分区号。解决思路一般我们会通过mapPartitionsWithIndex函数来打印分区数据。示例代码如下:自己定义分区器scala> import org.apache.spark.Partitionerimport org.apache.spark.Partitionerscala> class TwoPartsPartitioner(override val numPartitions:原创 2020-10-27 08:39:16 · 1908 阅读 · 0 评论 -
如何解决MetadataFetchFailedException错误?
问题描述有时候在一个环境中,但处理小数据量时并没有报错,但当数据量增大到某个量级时,就会出现类似以下的错误:org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0org.apache.spark.shuffle.FetchFailedException: Failed to connect to ip-xxxxxxxxorg.apache.spark.shuffle原创 2020-10-25 08:24:23 · 2812 阅读 · 0 评论 -
如何把同一个key的数据都写入到同一个文件/文件夹中?
问题的提出在进行数据处理时,我们经常遇到这样的需求:把同一个key的数据写到同一个文件/文件夹中。这样,在进行后续的处理,比如查看某个key占的磁盘空间,单独处理某个key的数据等都会非常方便。解决方案通过dataframe来解决这个问题很方便。方案就是:通过该key进行分区,这样同一个key的值就都分配到一个分区中了。val people_rdd = sc.parallelize(Seq((1, "alice"), (1, "bob"), (2, "charlie")))val people_原创 2020-10-23 09:09:47 · 573 阅读 · 0 评论 -
如何将一个很大的RDD安全的获取到本地?
本文介绍如何按分区取回RDD数据的方法。问题的提出有时需要把RDD或Dataframe的数据获取到本地进行保存或处理。一般的方法是使用collect()函数来操作,但若数据集的数据量很大,就会导致Driver端的OOM错误。此时,需要考虑使用其他方式来处理。问题的解决可以这样考虑,要是把整个RDD取回来不行,那么是否可以按分区把数据取回。val parts = rdd.partitionsfor (p <- parts) { val idx = p.index /原创 2020-10-22 07:15:10 · 269 阅读 · 0 评论 -
如何为spark的dataframe添加常量列
有时候由于数据处理需要,我们会为dataframe添加一个常量列,本文介绍向dataframe添加常量列的方法。使用typedLit函数通过函数:org.apache.spark.sql.functions.typedLit,可以添加List,Seq和Map类型的常量列。scala> val df1 = sc.parallelize(Seq("Hello", "world")).toDF()df1: org.apache.spark.sql.DataFrame = [value: string原创 2020-10-21 16:04:57 · 2950 阅读 · 0 评论 -
如何把dataframe直接保存到hive表中?
有多种方式把一个dataframe保存到hive表中:1.直接把dataframe的内容写入到目标hive表df.write().mode("overwrite").saveAsTable("tableName");或df.select(df.col("col1"),df.col("col2")) .write().mode("overwrite").saveAsTable("schemaName.tableName");或df.write().mode(SaveMode.Overwrite).原创 2020-10-13 09:13:23 · 4036 阅读 · 0 评论 -
spark sql实战—如何同时对多列进行sum,min,max等操作
概述有时我们希望某个聚合操作,比如:sum,avg等,能够作用到多个列上,也就是一次计算一个或多个列的聚合值。这样可以简化我们的代码。本文讲述如何在实战中把聚合操作使用到多个列上。实战19.如何把聚合函数使用到多个列上?python的写法>>> df = spark.createDataFrame([(1.0, 0.3, 1.0), (1.0, 0.5, 0.0), (-1.0, 0.6, 0.5), (-1.0, 5.6, 0.2)],("col1", "col2", "原创 2020-06-13 10:11:40 · 3864 阅读 · 0 评论 -
如何在spark-shell中调试运行scala文件
概述本文讲述如何通过spark-shell来调试scala代码文件,这样不需要IDE就可以对scala文件进行调试,在代码量较小的情况下比较适用。方法1:使用:load 命令有时候为了在spark-shell中调试一段代码,可以在spark-shell中使用:load 命令。如下:test.scala文件内容val df3 = Seq((100,"xiaoming",30)).toDF("id", "name","age")在spark-shell中加载该文件scala> :l原创 2020-06-11 08:51:42 · 7120 阅读 · 0 评论 -
Spark Sql实战--合并数据
数据的合并概述本文介绍如何通过spark sql对数据进行各种的合并操作,包括:列合并,行合并,相同key的合并等等。在实际的数据处理场景中,数据的合并操作非常常用,这里介绍如何通过spark sql来完成常用的合并操作。数据准备例子数据准备以下数据:name,address,age,id,timedavid,shenzhen,31,1,201903eason,shenzhen,27,2,201904jarry,wuhan,35,3,201904aarry2,wuhan1,34,4原创 2020-05-23 14:46:08 · 7877 阅读 · 0 评论 -
spark sql实战—拆分数据
拆分的数据有时在进行数据时我们需要把一列数据分割成多列数据,把一个字段值,分割成多个值。本节介绍如何通过spark sql提供的函数来进行数据的分割。1. 数据拆分概述数据拆分操作在进行数据处理时,通常我们需要对数据进行拆分。比如:把一列拆分成多行,多列,把一行拆分成多行,多列等。在spark-sql中提供了多个函数用来进行数据拆分。数据拆分的函数splitexplodepostexplodesubstring2. 数据的拆分2.1 通过explode系列函数进行拆分把一个数原创 2020-05-23 14:44:40 · 10657 阅读 · 0 评论 -
spark sql实战(pyspark)—如何把多个udf作用于同一列数据
概述本文介绍如何把多个udf函数使用到dataframe/dataset的同一列上。使用思路有时候我们需要在同一列上进行多个函数操作,形成一个函数链。也就是把上一个函数的输出作为下一个函数的输入,把最后的结果作为处理结果。有多种方式可以实现该功能,这介绍一种函数链的方式,基本思路如下:把需要对列进行处理的函数放到一个链表中分别通过函数链上的每个函数来对列数据进行处理把上一个函数的处...原创 2019-12-23 08:27:04 · 1067 阅读 · 0 评论 -
spark sql实战—加载csv文件到动态分区表
概述本文讲述如何通过spark sql把一个dataframe加载到spark的动态分区表中。场景介绍把csv和parquet文件加载到spark的动态分区表中,有很多中方案,这里介绍如何通过spark的dataframe把数据文件加载到动态分区表中。注意:为了保证性能,指定分区的字段的字典数据的唯一值最好不要超过几万。这是spark-2.3的partitionBy算子的源码的注释中写到的...原创 2019-12-23 08:26:05 · 805 阅读 · 0 评论