如何在CSV中使用双管作为分隔符?

时间:2016-12-21 17:05:34

标签: scala apache-spark

Spark 1.5和Scala 2.10.6

我有一个使用“||”作为分隔符的数据文件。我很难解析这个以创建数据框。可以使用多个分隔符来创建数据框吗?该代码适用于单个损坏的管道,但不适用于多个分隔符。

我的代码:

val customSchema_1 = StructType(Array(
    StructField("ID", StringType, true), 
    StructField("FILLER", StringType, true), 
    StructField("CODE", StringType, true)));

val df_1 = sqlContext.read
    .format("com.databricks.spark.csv")
    .schema(customSchema_1)
    .option("delimiter", "¦¦")
    .load("example.txt")

示例文件:

12345¦¦  ¦¦10

4 个答案:

答案 0 :(得分:4)

所以这里发出的实际错误是:

java.lang.IllegalArgumentException: Delimiter cannot be more than one character: ¦¦

文档证实了这个限制,我检查了Spark 2.0 csv阅读器,它有相同的要求。

考虑到所有这一切,如果您的数据足够简单,而您没有包含¦¦的条目,我会像这样加载您的数据:

scala> :pa
// Entering paste mode (ctrl-D to finish)
val customSchema_1 = StructType(Array(
    StructField("ID", StringType, true), 
    StructField("FILLER", StringType, true), 
    StructField("CODE", StringType, true)));

// Exiting paste mode, now interpreting.
customSchema_1: org.apache.spark.sql.types.StructType = StructType(StructField(ID,StringType,true), StructField(FILLER,StringType,true), StructField(CODE,StringType,true))

scala> val rawData = sc.textFile("example.txt")
rawData: org.apache.spark.rdd.RDD[String] = example.txt MapPartitionsRDD[1] at textFile at <console>:31

scala> import org.apache.spark.sql.Row
import org.apache.spark.sql.Row

scala> val rowRDD = rawData.map(line => Row.fromSeq(line.split("¦¦")))
rowRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[3] at map at <console>:34

scala> val df = sqlContext.createDataFrame(rowRDD, customSchema_1)
df: org.apache.spark.sql.DataFrame = [ID: string, FILLER: string, CODE: string]

scala> df.show
+-----+------+----+
|   ID|FILLER|CODE|
+-----+------+----+
|12345|      |  10|
+-----+------+----+

答案 1 :(得分:2)

我遇到了这个问题,找到了一个好的解决方案,我使用的是spark 2.3,我感觉它应该可以在所有spark 2.2+上正常工作,但是还没有测试。它的工作方式是将git reset替换为ORIG_HEAD,然后内置的csv可以接受Dataset[String]。我使用制表符是因为我的数据中有逗号。

||

希望这对其他人有帮助。

答案 2 :(得分:0)

我们尝试通过以下方式读取具有自定义分隔符并为数据框自定义列名称的数据,

# Hold new column names saparately
headers ="JC_^!~_*>Year_^!~_*>Date_^!~_*>Service_Type^!~_*>KMs_Run^!~_*>

# '^!~_*>' This is field delimiter, so split string
head = headers.split("^!~_*>")

## Below command splits the S3 file with custom delimiter and converts into Dataframe
df = sc.textFile("s3://S3_Path/sample.txt").map(lambda x: x.split("^!~_*>")).toDF(head)

在toDF()中将head作为参数传递给从具有自定义分隔符的文本文件创建的数据框分配新的列名称。

希望这会有所帮助。

答案 3 :(得分:0)

从Spark2.8及更高版本开始,添加了对多字符定界符的支持。 https://issues.apache.org/jira/browse/SPARK-24540

@lockwobr提出的上述解决方案可在scala中使用。在Spark 2.8以下工作并在PySpark中寻求解决方案的人,可以参考以下内容

flight

我提供了一个示例,但是您可以根据自己的逻辑对其进行修改。

相关问题