要计算Spark RDD或DataFrame中列之间的分隔符,并将行移动到单独的RDD或Dataframe中

时间:2019-02-06 11:40:47

标签: scala apache-spark pyspark apache-spark-sql

我是火花编程的新手,正在将多个TSV.gz文件加载到RDD或数据帧中。我想计算一下加载后各列之间的制表符数量,并根据以下条件将数据行移动到单独的RDD或数据帧中。

总列数= 996

If the number of tab counts = 995 -> move to another RDD or DF
If the number of tab counts < 995 -> move to another RDD or DF
If the number of tab counts > 995 -> move to another RDD or DF

我尝试了以下操作,但返回的是布尔值

val textFile = sc.textFile("/abc/*.tsv.gz")
textFile.map(line=>line.split("\t"))
val file1 = textFile.filter(line => line.contains("\t").count() > 995)
val file2 = textFile.filter(line => line.contains("\t").count() < 995)

请让我知道是否可以实现

谢谢!!

2 个答案:

答案 0 :(得分:0)

首先,从Spark 2.0开始,强烈建议您坚持使用SparkSQL,除非您需要对RDD进行一些低级访问。情况并非如此,因此在学习时可以随意忘记RDD。

您可以尝试通过几种方法来实现。假设TSV具有标题行,或者您可以为该列分配名称。利用CSV格式阅读器,只需使用\t作为分隔符即可:

val all = spark.read
  .format("csv")
  .option("header", "true")
  .option("delimiter", "\t")
  .option("inferSchema", "true")
  .load("file.tsv")

接下来,假设left是列994的名称,center是列995的名称,right是列996的名称。

val left = all.filter(col("center").isNull)
val center = all.filter(col("center").isNotNull && col("right").isNull)
val right = all.filter(col("right").isNotNull)

答案 1 :(得分:0)

如果文件是csv,请始终使用数据框。您可以使用df.columns.length来提供csv文件中的列数。 这是具有8列的csv文件的示例代码。您可以对996列进行相应的修改。

emp1.csv的内容

7369     "SMITH"     "CLERK"     7902    "17-Dec-80"     800     20  10
7499     "ALLEN"     "SALESMAN"  7698    "20-Feb-81"     1600    300     30

火花代码

import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql._
object StackOverflow {
  def main(args: Array[String]) {
    Logger.getLogger("org").setLevel(Level.ERROR)
    val spark = SparkSession.builder().appName("Testing..").master("local[*]").getOrCreate()
    import spark.implicits._

    val emp1 = spark.read.format("csv").option("delimiter","\t").load("in/emp1.csv")
    emp1.show(false)
    val col_len = emp1.columns.length
    if(col_len == 8) {
      val df1 = emp1.toDF("empno", "ename", "job", "mgr", "hiredate", "sal", "comm", "deptno")
      df1.show(false)
    }
    if(col_len== 7) {
      val df2 = emp1.toDF("empno", "ename", "job", "mgr", "hiredate", "sal", "comm")
      df2.show(false)
    }

  }
}