IntelliJ idea 是一个优秀的IDE,我们可以用它做java、Scala的开发。新版本的已经默认不再推断变量类型了,我们可以手动开启类型推断的效果–specify type.
File–>Settings–>Editor–>Code Style–>Scala–>Type Annotations 勾选上 Local definition
Intellij IDEA 2018.3.6
嗨,无聊么
IntelliJ idea 是一个优秀的IDE,我们可以用它做java、Scala的开发。新版本的已经默认不再推断变量类型了,我们可以手动开启类型推断的效果–specify type,以后声明变量就会自动推断类型
大数据方向的 分析师 利用scala spark dataframe 进行表的转置,透视表,行专列,列转行,合并列,多行合并等操作
scala spark dataframe 是大数据从业者必须掌握的基础知识点。 对于数据分析人员经常会有对数据表进行转置/透视的需求,还有对数据进行行转列,列转行,多列多行合并的处理。无论哪种情况,对于常年使用SQL语句来进行数据分析的技术人员应该都是信手拈来的操作,但是对于很大使用大数据组件Spark来进行数据处理和分析的选手来说可能就需要了解除了常规SQL之外的操作方式了。
val spark = SparkSession .builder() .appName("HelloWorld") .getOrCreate() import spark.implicits._ val data = spark.sparkContext.parallelize(List( ( 1, "张三", 88.0, "Mat"), ( 2, "李四", 67.0, "Mat"), ( 3, "赵六", 77.0, "Mat"), ( 4, "王五", 65.0, "Mat"), ( 1, "张三", 77.0, "Eng"), ( 2, "李四", 90.0, "Eng"), ( 3, "赵六", 24.0, "Eng"), ( 4, "王五", 90.0, "Eng"), ( 1, "张三", 33.0, "Chinese"), ( 2, "李四", 87.0, "Chinese"), ( 3, "赵六", 92.0, "Chinese"), ( 4, "王五", 87.0, "Chinese") )) val df = data.toDF("id","name","scores","class_names").cache() df.show(false) val _cla = df.select("class_names").distinct().rdd.map(_ (0).toString).collect() print(_cla.toList)
# dataframe show +---+----+------+-----------+ |id |name|scores|class_names| +---+----+------+-----------+ |1 |张三 |88.0 |Mat | |2 |李四 |67.0 |Mat | |3 |赵六 |77.0 |Mat | |4 |王五 |65.0 |Mat | |1 |张三 |77.0 |Eng | |2 |李四 |90.0 |Eng | |3 |赵六 |24.0 |Eng | |4 |王五 |90.0 |Eng | |1 |张三 |33.0 |Chinese | |2 |李四 |87.0 |Chinese | |3 |赵六 |92.0 |Chinese | |4 |王五 |87.0 |Chinese | +---+----+------+-----------+ # 三门课程 List(Eng, Chinese, Mat)
以下代码是通过dataframe的pivot方法,按照名字分组,分组后去第一个分数;最终实现转置表或者是透视表的效果。
val _pivot = df.groupBy("name").pivot("class_names", _cla).agg(functions.first("scores")) _pivot.show(false)
+----+----+-------+----+ |name|Eng |Chinese|Mat | +----+----+-------+----+ |王五 |90.0|87.0 |65.0| |李四 |90.0|87.0 |67.0| |赵六 |24.0|92.0 |77.0| |张三 |77.0|33.0 |88.0| +----+----+-------+----+
而如果想要把透视表逆转回去就要用hive 的stack函数来实现,而spark dataframe中没有相关的方法,具体实现如下两种实现方式的代码;但是有两个知识点要注意下
_pivot.select($"Name", unctions.expr("stack(3, 'Analytics', Mat, 'BI', Eng, 'Ingestion', Chinese) as (kecheng, fenshu)")).show(false) # 相同效果的实现方式 // _pivot.selectExpr("name","stack(3, 'Analytics', Mat, 'BI', Eng, 'Ingestion', Chinese) as (kecheng, fenshu)").show(false)
+----+---------+------+ |Name|kecheng |fenshu| +----+---------+------+ |王五 |Analytics|65.0 | |王五 |BI |90.0 | |王五 |Ingestion|87.0 | |李四 |Analytics|67.0 | |李四 |BI |90.0 | |李四 |Ingestion|87.0 | |赵六 |Analytics|77.0 | |赵六 |BI |24.0 | |赵六 |Ingestion|92.0 | |张三 |Analytics|88.0 | |张三 |BI |77.0 | |张三 |Ingestion|33.0 | +----+---------+------+
df.groupBy("name").agg(functions.concat_ws(",",functions.collect_set($"scores".cast("string"))).as("fenshu")).show(false)
+----+--------------+ |name|fenshu | +----+--------------+ |王五 |90.0,65.0,87.0| |李四 |67.0,90.0,87.0| |赵六 |77.0,92.0,24.0| |张三 |88.0,77.0,33.0| +----+--------------+
通过functions的split 方法把字符串类型的列先转换成Array类型,之后在通过explode方法把Array转换成多行
import org.apache.spark.sql.functions val res = df.groupBy("name").agg(functions.concat_ws(",",functions.collect_set($"scores".cast("string"))).as("fenshu")) res.show(false) res.select($"name", functions.explode(functions.split($"fenshu", ",")).as("score")).show(false)
# 多个数值在一列中 +----+--------------+ |name|fenshu | +----+--------------+ |王五 |90.0,65.0,87.0| |李四 |67.0,90.0,87.0| |赵六 |77.0,92.0,24.0| |张三 |88.0,77.0,33.0| +----+--------------+
# 一列数据拆分成多行 +----+-----+ |name|score| +----+-----+ |王五 |90.0 | |王五 |65.0 | |王五 |87.0 | |李四 |67.0 | |李四 |90.0 | |李四 |87.0 | |赵六 |77.0 | |赵六 |92.0 | |赵六 |24.0 | |张三 |88.0 | |张三 |77.0 | |张三 |33.0 | +----+-----+
Mac m1 brew install spark。大数据组件spark入门学习时会有很多系统性的知识需要我们去学习,比如在大数据整个生态圈里spark、Hadoop等组件的角色定位、价值、应用方向、系统安装等。正是这个系统性的思维模式会让我们在各个计算机系统环境中布置spark的时候都惯性的先把Hadoop环境搭建好再依次搭建spark,实际上在Mac笔记本本地安装spark组件的时候是可以不安装Hadoop的,毕竟大多数在Mac上安装spark是为了一些rdd语法的练习,不是为了大量数据的处理。
Mac本身只有自己的软件管理工具的,类似于我们用Linux系统,不同的内核用不同的命令来安装所需的软件或者工具包,如yum, apt-get等。Mac的软件包管理命令是 brew,安装spark环境所需要的所有的软件包都可以用brew来管理。
java version “1.8.0_291” java的安装和环境配置可以通过 文章: http://www.lifefunker.com/archives/51, 来了解具体的操作。有一个事情强调一下,没有bash_profile文件就别自己画蛇添足非要新建一个了…..,没有是因为真的它不再叫这个名字了,找个.zshrc 文件
通过brew安装软件主要也是三步骤:
~ % brew search spark ==> Formulae apache-spark ✔ spark sparkey spack sparse par ==> Casks spark spark-ar-studio sparkle sparkleshare
命令brew search spark 顾名思义就是查找spark软件包,可以看到返回多个结果,这些结果都是名称,我们要安装的时候都是install对应的名称即可。但是我们发现有Formulae和Casks两个不同的,一般我们按Formulae。
~ % brew info apache-spark apache-spark: stable 3.2.1 (bottled), HEAD Engine for large-scale data processing https://spark.apache.org/ /usr/local/Cellar/apache-spark/3.2.1 (1,472 files, 322MB) * Poured from bottle on 2022-05-16 at 17:36:18 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/apache-spark.rb License: Apache-2.0 ==> Dependencies Required: openjdk@11 ✔ ==> Options --HEAD Install HEAD version ==> Analytics install: 4,389 (30 days), 13,792 (90 days), 54,640 (365 days) install-on-request: 4,387 (30 days), 13,777 (90 days), 54,556 (365 days)
~ % brew info spark Warning: Treating spark as a formula. For the cask, use homebrew/cask/spark spark: stable 1.0.1 (bottled) Sparklines for the shell https://zachholman.com/spark/ Not installed From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/spark.rb License: MIT ==> Analytics install: 559 (30 days), 1,612 (90 days), 5,995 (365 days) install-on-request: 544 (30 days), 1,566 (90 days), 5,834 (365 days) build-error: 0 (30 days)
通过brew info 我们分别查看了 apache-spark 和 spark 的两个软件包的信息,可以看到spark的版本太老旧了,至此我们决定安装apache-spark。
brew install apache-spark
安装完成后,环境变量一般是不会有可执行的命令的,需要我们去zshrc文件中添加对应的sparkhome,但是如果不想那么麻烦就直接去安装的路径下,找到对应的spark-shell文件添加软链来快速打开即可。