日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
- Impala 操作/读写 Kudu,使用druid连接池
- Kudu 原理、API使用、代码
- Kudu Java API 条件查询
- spark读取kudu表导出数据为parquet文件(spark kudu parquet)
- kudu 导入/导出 数据
- Kudu 分页查询的两种方式
- map、flatMap(流的扁平化)、split 的区别
- spark程序打包为jar包,并且导出所有第三方依赖的jar包
-
spark提交命令 spark-submit 的参数 executor-memory、executor-cores、num-executors、spark.default.parallelism分析
1.flatMap:
流的扁平化,最终输出的数据类型为一维数组Array[String]。
被分割出来的每个数据都作为同一个数组中的相同类型的元素,最终全部被分割出来的数据都存储于同一个一维数组中。
结论:多行数据被分割后都存储到同一个一维数组Array[String]中。
2.map:
最终输出的数据类型为二维数组Array[Array[String]]。
以相同分隔符分割出来的数据存储到同一个一维数组Array[String]中,一旦遇到分隔符所无法分割的位置(如遇到回车换行符时)时,
便创建出一个新的一维数组Array[String],后面所分割的数据则都存储到新的一维数组Array[String]中,
即分隔符所无法分割的位置作为新建一维数组Array[String]的标志。
结论:一行数据就为一个一维数组Array[String],多行数据就有多个一维数组,最终多个一维数组一起被封装到同一个一维数组中。
=====================================================
读取本地文件,实现文件内的单词计数。
本地文件 /root/scala/words.txt 内容如下:
hello me
hello you
hello her
sc.textFile("file:///root///scala///words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect
输出 res0: Array[(String, Int)] = Array((hello,3), (me,1), (you,1), (her,1))
解析:
1.flatMap(_.split(" ")):输出数据 Array[String] = Array(hello,me,hello,you,hello,her)
使用空格作为换行分隔符,被分割出来的每个数据都作为同一个数组中的相同类型的元素,最终全部被分割出来的数据都存储于同一个一维数组中。
同时还会以回车换行符作为默认的分隔符,即回车换行符前面的数据也会被自动进行分割,而回车换行符后面所分割出来的数据同样存储于同一个一维数组中。
2.map(_.split(" ")):输出数据 Array[Array[String]] = Array(Array(hello,me),(Array(hello,you),(Array(hello,her))
使用空格作为换行分隔符,以相同分隔符分割出来的数据存储到同一个一维数组Array[String]中,最终输出的数据类型为二维数组Array[Array[String]]。
同时还会以回车换行符作为新建一维数组Array[String]的标志,而回车换行符后面所分割的数据则都存储到新的一维数组Array[String]中。
3.map((_,1)):
map()首先表示遍历出数组中的每个元素。
flatMap(_.split(" ")).map((_,1)):遍历出的是每个字符串 hello,me,hello,you,hello,her
map(_.split(" ")).map((_,1)):遍历出出的是每个Array数组 Array(hello,me),Array(hello,you),Array(hello,her)
=====================================================
val rdd1 = sc.parallelize(Seq(("one two three four five six seven"), ("one two three four five six seven"), ("one two three four five six seven")))
rdd1.map(_.split(" ")).collect
/*
res6: Array[Array[String]] = Array(Array(one, two, three, four, five, six, seven),
Array(one, two, three, four, five, six, seven),
Array(one, two, three, four, five, six, seven))
*/
rdd1.flatMap(_.split(" ")).collect
/*
res7: Array[String] = Array(one, two, three, four, five, six, seven,
one, two, three, four, five, six, seven,
one, two, three, four, five, six, seven)
*/
val rdd2 = sc.parallelize(Seq((1, "one two three four five six seven"), (2, "one two three four five six seven"), (3, "one two three four five six seven")))
rdd2.map(x => (x._1, x._2.split(" "))).collect
/*
res14: Array[(Int, Array[String])] = Array((1,Array(one, two, three, four, five, six, seven)),
(2,Array(one, two, three, four, five, six, seven)),
(3,Array(one, two, three, four, five, six, seven)))
*/
rdd2.map(x =>
{
val x2 = x._2.split(" ")
(x._1, x2.toIterable)
}).collect
/*
res4: Array[(Int, Iterable[String])] = Array((1,WrappedArray(one, two, three, four, five, six, seven)),
(2,WrappedArray(one, two, three, four, five, six, seven)),
(3,WrappedArray(one, two, three, four, five, six, seven)))
*/
rdd2.map(x =>
{
val x2 = x._2.split(" ")
(x._1, x2.toIterable)
}).flatMap
{ x =>
val y = x._2
for (w <- y) yield (x._1, w)
}.collect
/*
res7: Array[(Int, String)] = Array((1,one), (1,two), (1,three), (1,four), (1,five), (1,six), (1,seven),
(2,one), (2,two), (2,three), (2,four), (2,five), (2,six), (2,seven),
(3,one), (3,two), (3,three), (3,four), (3,five), (3,six), (3,seven))
*/
===============================================================================================
scala> val s = "eggs, milk, butter, Coco Puffs" //除第一个单词外的每个单词前面都带有空格
s: String = eggs, milk, butter, Coco Puffs
scala> s.split(",")
res9: Array[String] = Array(eggs, " milk", " butter", " Coco Puffs") //除第一个单词外的每个单词前面都带有空格
scala> val s1 = "eggs,milk,butter, Coco Puffs" //只有最后一个单词的前面带有空格
s1: String = eggs,milk,butter, Coco Puffs
scala> s1.split(",")
res10: Array[String] = Array(eggs, milk, butter, " Coco Puffs")//只有最后一个单词的前面带有空格
scala> val s = "eggs, milk, butter, Coco Puffs"
s: String = eggs, milk, butter, Coco Puffs
scala> s.split(",").map(_.trim) //trim 去掉“被分割出来的每个字符串前后面的”空格字符
res11: Array[String] = Array(eggs, milk, butter, Coco Puffs)
===============================================================================================
//要处理的字符串数据为:"中国|美国|英国"。目的是希望切开得到每个国家("中国","美国","英国"),然而结果却是("中","国","美","国","英","国")
import org.apache.spark.sql.functions._
split(data(field), "|")) //data是一个Spark DataFrame,其中的field字段是由竖杠|隔开的字符串(如:"中国|美国|英国")
//要处理的字符串数据为:"中国|美国|英国"。而结果正是切开得到每个国家("中国","美国","英国")
import org.apache.spark.sql.functions._
split(data(field), "\\|"))
===============================================================================================
String中的 split(",") 和 split(",",-1) 的区别
1、当准备要被切割处理的字符串的最后一位有值(非分隔符)时,两者没有区别。
2、当准备要被切割处理的字符串的最后一位或者最后N位全部都是分隔符,而并非正常数据时,split(",")不会继续切分,并且不保留为null值,
而split(",",-1)继续进行切分,并且保留出null值作为被切割出来的数据。
package stringsplit;
public class stringSplit
{
public static void main(String[] args)
{
String line = "hello,,world,,,";
String res1[] = line.split(",");
String res2[] = line.split(",", -1);
int i=1;
for(String r: res1)
System.out.println(i+++r);
System.out.println("========================");
i=1;
for(String r: res2)
System.out.println(i+++r);
}
输出结果是:
1hello
2
3world
========================
1hello
2
3world
4 //保留为null值作为被切割出来的数据
5 //保留为null值作为被切割出来的数据
6 //保留为null值作为被切割出来的数据