【问题标题】:Scala - how to pass delimiter as a variable when writing dataframe as csvScala - 将数据帧写入csv时如何将分隔符作为变量传递
【发布时间】:2019-01-30 11:17:27
【问题描述】:

使用变量作为 dataframe.write.csv 的分隔符不起作用。尝试替代方案太复杂了。

 val df = Seq(("a", "b", "c"), ("a1", "b1", "c1")).toDF("A", "B", "C")
 val delim_char = "\u001F"

 df.coalesce(1).write.option("delimiter", delim_char).csv("file:///var/tmp/test")  // Does not work -- error related to too many chars
 df.coalesce(1).write.option("delimiter", "\u001F").csv("file:///var/tmp/test")  //works fine...

我已经尝试过 .toHexString 以及许多其他的替代方案......

【问题讨论】:

  • 当您提供直接字符串值或传递保存字符串值的变量时,它适用于两者。如果在声明 '\u001F' 时使用单引号,则会出现字符长度过多的问题,但对于使用双引号 "\u001F" 时的上述声明,您应该不会遇到任何问题。
  • @Mansoor,如上所述,它在 Scala 2.11.8 中不起作用...任何帮助将不胜感激。

标签: scala csv dataframe export delimiter


【解决方案1】:

您的声明效果很好。当您提供直接字符串值或传递引用变量时,它适用于两者。只有将分隔符值括在单引号 '\u001F' 中时,才会出现字符长度错误。与Scala 2.11.8无关。

Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Spark context Web UI available at http://xx.x.xxx.xx:xxxx
Spark context available as 'sc' (master = local[*], app id = local-1535083313716).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.2.0.2.6.3.0-235
      /_/

Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144)
Type in expressions to have them evaluated.
Type :help for more information.

scala> import java.io.File
import java.io.File

scala> import org.apache.spark.sql.{Row, SaveMode, SparkSession}
import org.apache.spark.sql.{Row, SaveMode, SparkSession}

scala> val warehouseLocation = new File("spark-warehouse").getAbsolutePath
warehouseLocation: String = /usr/hdp/2.6.3.0-235/spark2/spark-warehouse

scala> val spark = SparkSession.builder().appName("app").config("spark.sql.warehouse.dir", warehouseLocation).enableHiveSupport().getOrCreate()
18/08/24 00:02:25 WARN SparkSession$Builder: Using an existing SparkSession; some configuration may not take effect.
spark: org.apache.spark.sql.SparkSession = org.apache.spark.sql.SparkSession@37d3e740

scala> import spark.implicits._
import spark.implicits._

scala> import spark.sql
import spark.sql

scala> val df = Seq(("a", "b", "c"), ("a1", "b1", "c1")).toDF("A", "B", "C")
df: org.apache.spark.sql.DataFrame = [A: string, B: string ... 1 more field]

scala> val delim_char = "\u001F"
delim_char: String = ""

scala> df.coalesce(1).write.option("delimiter", delim_char).csv("file:///var/tmp/test")

scala>

【讨论】:

  • 感谢您的检查。在我的系统上,我收到 java.lang... 与传递的多个字符有关的错误。
  • @Shiva 你能在这里分享堆栈跟踪吗?
【解决方案2】:

感谢您的帮助。

上面的代码在测试时有效,但我找不到展示问题是如何产生的方法。但是,问题是,在从 csv 文件中收集到一个字符串后,有一个变量分配给了一个字符串(它是 Unicode“\u001F”,println 将结果显示为字符串:\u001F)。

尝试了几种方法。终于在另一个Stackoverflow question related to string unicode找到了解决办法...

1) 不起作用 -- delim_char.format("unicode-escape")

2) 工作--

def unescapeUnicode(str: String): String = 
     """\\u([0-9a-fA-F]{4})""".r.replaceAllIn(str, 
     m => Integer.parseInt(m.group(1), 16).toChar.toString)

unescapeUnicode(delim_char)

【讨论】:

    猜你喜欢
    • 2019-04-21
    • 2014-03-07
    • 1970-01-01
    • 2014-05-11
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多