当前位置: 首页 > 知识库问答 >
问题:

火花-从CSV文件中删除标题和拖尾

江鸿羲
2023-03-14

我正在尝试接收表中的CSV文件,但在此之前,我需要根据头文件和尾文件进行一些验证。

样本数据

Header,TestApp,2020-01-01,
name, dept, age, batchDate
john, dept1, 33, 2020-01-01
john, dept1, 33, 2020-01-01
john, dept1, 33, 2020-01-01
john, dept1, 33, 2020-01-01
Trailer,count,4

现在,在我将数据摄取到表中之前,我需要检查每个拖车记录的记录总数是否为5。

这就是我正在做的正确的事情。

val df = spark.read.format("csv").load("/tmp/test.csv")
val indexed = df.withColumn("index", monotonicallyIncreasingId())
val last = indexed.agg(max($"index")).collect()(0)(0).asInstanceOf[Long]
//Remove header and Trailer record
val filtered  = indexed.filter($"index" < last).filter($"index" >= 1)

//Write file without extra header and trailer, it still have column name
filtered.write.format("com.databricks.spark.csv").save("/tmp/test1")

//Read back with infer schema
val df1 = spark.read.format("csv").option("header", "true").option("inferSchema", "true").load("/tmp/test1")

//Count Validation
val count = indexed.filter($"index" === last).select("_c1").collect()(0)(0).asInstanceOf[String].toInt
assert(df.count == count)

我在想,如果有更好的方法来避免写回文件来创建第二个数据帧。我说的是第五步。

我想从列标题(文件的第二行)最后的数据帧与ferschme列标题

共有1个答案

陈淳
2023-03-14
import spark.implicits._
import org.apache.spark.sql.{Column, Encoders, SparkSession}
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.functions.{col, trim}

val df1 = spark.read.option("header", false).csv(f)

val colNames = List("name", "dept", "age", "batchDate")
val df2 = df1
  .filter('_c0 =!= "Header")
  .filter('_c0 =!= "Trailer")
  .filter('_c0 =!= "name")
df2.show(false)

//  +----+------+---+-----------+
//  |_c0 |_c1   |_c2|_c3        |
//  +----+------+---+-----------+
//  |john| dept1| 33| 2020-01-01|
//  |john| dept1| 33| 2020-01-01|
//  |john| dept1| 33| 2020-01-01|
//  |john| dept1| 33| 2020-01-01|
//  +----+------+---+-----------+

val df3 = df2.toDF(colNames: _*)

df3.show(false)
//    +----+------+---+-----------+
//    |name|dept  |age|batchDate  |
//    +----+------+---+-----------+
//    |john| dept1| 33| 2020-01-01|
//    |john| dept1| 33| 2020-01-01|
//    |john| dept1| 33| 2020-01-01|
//    |john| dept1| 33| 2020-01-01|
//    +----+------+---+-----------+

df3.printSchema()
//  root
//  |-- name: string (nullable = true)
//  |-- dept: string (nullable = true)
//  |-- age: string (nullable = true)
//  |-- batchDate: string (nullable = true)

case class SchemaClass(name: String, dept: String, age: Int, batchDate: String)
val schema: StructType    = Encoders.product[SchemaClass].schema
val sch = df3.schema
val schemaDiff = schema.diff(sch)

val rr = schemaDiff.foldLeft(df3)((acc, clmn) => {
  acc.withColumn(clmn.name , trim(col(clmn.name)).cast(clmn.dataType))
})

rr.show(false)
//  +----+------+---+-----------+
//  |name|dept  |age|batchDate  |
//  +----+------+---+-----------+
//  |john| dept1|33 | 2020-01-01|
//  |john| dept1|33 | 2020-01-01|
//  |john| dept1|33 | 2020-01-01|
//  |john| dept1|33 | 2020-01-01|
//  +----+------+---+-----------+


rr.printSchema
//  root
//  |-- name: string (nullable = true)
//  |-- dept: string (nullable = true)
//  |-- age: integer (nullable = true)
//  |-- batchDate: string (nullable = true)
 类似资料:
  • 如何使用java spark从spark数据帧中删除csv文件中的所有特殊字符例如:以下是包含空格和特殊字符的csv文件内容 o/p我需要 提前感谢

  • 我有n个需要连接的csv文件。问题是我需要从每个文件中删除头文件。 我尝试过使用这些tail-n2$INPUT\u FILE\u PATH/$FILE ***这会将文件名和路径放入新文件中 == == 我试过了 ***仅从第一个文件中删除标头。 校长1,校长2,校长3,校长4 我怎样才能得到结果呢

  • 问题内容: 我尝试在Java中删除csv文件中的列。 例如,我有这个csv文件 我想要下一个操作后:(删除csvFile,2)将是: 我发现只有调用行而不是列的操作。 问题答案: 删除CSV文件中一列的唯一方法是删除整个文件(即文件的每一行)的标题和该列的信息。即使您使用第三方库,它也会在内部进行。

  • 我正在开发一个应该删除命名列的小PowerShell脚本。有没有办法不选择标题为“xyz”的列? 我试图通过 并将结果连接到逗号分隔的字符串中并删除不需要的标头 然后使用

  • 通常我可以做到这一点,没有任何问题,但我删除了一些语法在这里,当我继续并删除日期从页面标题在这段代码: 如何删除日期而不删除整个页面?

  • 问题内容: 我需要使用sed命令使用bash脚本从html中删除所有标签。我尝试了这个 和这 但我仍然想念什么,有什么建议吗? 问题答案: 您可以使用许多HTML到文本转换器之一,可以使用Perl regex,或者必须使用 如果没有错误的余地,请改用HTML解析器。例如,当元素分布在两行上时 此正则表达式将不起作用。 这正则表达式由三个部分组成,, 寻找开放 后面跟着零个或多个字符(不是结尾) 是