前言
在运行例子的时候. 遇到需要去除表头的情况. 将一般的几种做法记录于此.
- 文件
班级ID 姓名 年龄 性别 科目 成绩
12 张三 25 男 chinese 50
12 张三 25 男 math 60
12 张三 25 男 english 70
12 李四 20 男 chinese 50
12 李四 20 男 math 50
12 李四 20 男 english 50
12 王芳 19 女 chinese 70
12 王芳 19 女 math 70
12 王芳 19 女 english 70
13 张大三 25 男 chinese 60
13 张大三 25 男 math 60
13 张大三 25 男 english 70
13 李大四 20 男 chinese 50
13 李大四 20 男 math 60
13 李大四 20 男 english 50
13 王小芳 19 女 chinese 70
13 王小芳 19 女 math 80
13 王小芳 19 女 english 70
相关操作-个人选择
- 去除第一行
# 使用textFile读取整个文件.
JavaRDD<String> examLinesRDD = SeanSparkConfig.sparkContext.textFile(SeanSparkConfig.exameDateFilePath);
# 读取文件第一行
String firstLine = examLinesRDD.first();
JavaRDD<Student> studentRDD;studentRDD = examLinesRDD.
filter(line -> !line.equals(firstLine)). // 去除第一行表头
其实使用filter()
算子过滤我们需要抛弃的行是最容易的操作.
其余相关操作(参考1)
参考1
delcomments = ["嗯嗯嗯嗯", "啦啦啦", "买买买买"]
def delcom(line):
for i in delcomments:
if i in line:
return 1
return 0
comment = comment.filter(lambda line: delcom(line) != 1)
参考2
# 使用zipWithIndex算子
rdd.zipWithIndex().filter(_._2>=n).keys // n换成对应的第几列即可
参考3-比较详细
- 方法1-zipWithIndex 索引法.
val path = "files/data.txt"
val rdd = sc.textFile(path)
println("分区数:" + rdd.getNumPartitions)
val rdd1 = rdd.zipWithIndex()
//过滤掉索引小于等于2的
val rdd2 = rdd1.filter(_._2 > 2)
rdd1.foreach(println)
println("**********分割线***********")
rdd2.map(kv => kv._1).foreach(println)
根据统计. 其与分片无关. 但是当数据量过多时, 加索引产生性能问题.
- 方法2-take/fileter 法
val path = "files/data.txt"
val rdd = sc.textFile(path, 8)
println("分区数:" + rdd.getNumPartitions)
//前三条
val arr = rdd.take(3)
//过滤掉arr里的数据
val rdd3 = rdd.filter(!arr.contains(_))
rdd3.foreach(println)
- 方法3-Linux相关命令
# 查询原文件
cat data.txt
# 新建覆盖文件
tail -n+4 data.txt > data_new.txt
# 替换
mv data_new.txt data.txt
文件过大可能会有问题?
总结
其实思路非常简单. 查询出你需要过滤的数据, 使用filter
算子进行过滤即可.
对于不同分片上的数据. 你可以考虑写死代码的方式.
即String toFilter="姓名 年龄 ID 性别"; rdd.filter(str->!str.equals(toFilter))
.
还有一点值得注意的是, 使用equals
替换==
. 因为多个Executor
的情况下, 是在不同JVM
中的.