首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当foldLeft应用于dataFrame时,如何理解输出数据?

当foldLeft应用于dataFrame时,如何理解输出数据?
EN

Stack Overflow用户
提问于 2018-08-27 11:56:34
回答 1查看 877关注 0票数 1

我试图使用Scala中的foldLeft & regex_replace从Dataframe的字符串列中删除新的行字符。在读取了postgres上的关系数据库管理系统表: public.test_sid之后创建了数据。该表有4列:id, id1, id2, id3id3中有一个新的行字符。我就是这样写逻辑的:

代码语言:javascript
复制
var conf  = new SparkConf().setAppName("Spark-JDBC").set("spark.executor.heartbeatInterval","120s").set("spark.network.timeout","12000s").set("spark.default.parallelism", "20")
val conFile       = "testconnection.properties"
val properties    = new Properties()
properties.load(new FileInputStream(conFile))
val connectionUrl = properties.getProperty("gpDevUrl")
val devUserName   = properties.getProperty("devUserName")
val devPassword   = properties.getProperty("devPassword")
val driverClass   = properties.getProperty("gpDriverClass")
try {
  Class.forName(driverClass).newInstance()
} catch {
  case cnf: ClassNotFoundException =>
    System.exit(1)
  case e: Exception =>
    System.exit(1)
}
def main(args: Array[String]): Unit = {
  val spark = SparkSession.builder().config(conf).master("yarn").enableHiveSupport().getOrCreate()
  import spark.implicits._
  val spColsDF = spark.read.format("jdbc").option("url",connectionUrl).option("dbtable", "(select * from public.test_sid) as sampleTab").option("user", devUserName).option("password", devPassword).load()
  val strCols = spColsDF.schema.fields.filter(_.dataType==StringType).map(_.name)
  val finalDF = strCols.foldLeft(spColsDF){ (tempdf, colName) => tempdf.withColumn(colName, regexp_replace(col(colName), "\\n", " ")) }
  println("----------------------------------------------------------------------------------")
  spColsDF.show()
  println("----------------------------------------------------------------------------------")
  finalDF.show()
  println("----------------------------------------------------------------------------------")
}

在dataFrame:spColsDF的输出日志中,我看到了插入的格式的数据。

代码语言:javascript
复制
+--------------------+--------------------+----+---+
|                  id|                 id1| id2|id3|
+--------------------+--------------------+----+---+
|1.000000000000000000|1.000000000000000000|   a|
a|
+--------------------+--------------------+----+---+

但是finalDF中的数据以一种奇怪的格式显示出来。最后一列: id3的值出现在dataframe的开头,第一列的第一个数字: id被截断并表示为'000000000000000000‘而不是'1.000000000000000000’。

代码语言:javascript
复制
+--------------------+--------------------+----+---+
|                  id|                 id1| id2|id3|
+--------------------+--------------------+----+---+
 a|000000000000000000|1.000000000000000000|   a|
+--------------------+--------------------+----+---+

列的数据:id3优先

如果我只是从id3访问特定的列: finalDF,我将得到如下数据:

代码语言:javascript
复制
scala> finalDF.select(finalDF("id3")).show
+---+
|id3|
+---+
 a|
+---+

scala> finalDF.select(finalDF("id")).show
+--------------------+
|                  id|
+--------------------+
|1.000000000000000000|
+--------------------+

这只是打印数据时的控制台问题,还是代码中存在缺陷?如果我上面写的代码有什么问题,有人能告诉我吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-27 12:30:51

看起来像个CRLF。\r)问题。

历史上,一个用来告诉控制台在行的开头返回,另一个用来创建一个新的行。

在这里,你似乎抑制了新行的创建,但仍然有“回到起点”的部分。

因此,我建议您将替换为 \r\n

请参阅CR上的维基百科

回车,有时称为盒式回车,通常缩短为CR,或返回,是一种控制字符或机制,用于将设备的位置重置到一行文本的开头。它与行提要和换行符概念密切相关,尽管它本身可以单独考虑。

要查看它的运行情况,让我们创建一个测试数据文件:

代码语言:javascript
复制
scala> val dataframe = Seq(
     ("normal", "normal"), 
     ("withLF", "normal\n"), 
     ("withCRLF", "normal\r\n")).toDF("id", "value")
dataframe: org.apache.spark.sql.DataFrame = [id: string, value: string]

scala> dataframe.show
+--------+--------+
|      id|   value|
+--------+--------+
|  normal|  normal|
|  withLF| normal
|
|withCRLF|normal
|
+--------+--------+

在这里,我们看到带有"\r\n“和"\n”的字符串有您在帖子开始时观察到的问题。现在,如果我使用您替换函数:

代码语言:javascript
复制
dataframe.withColumn("value", regexp_replace($"value", "\n", "")).show
+--------+-------+
|      id|  value|
+--------+-------+
|  normal| normal|
|  withLF| normal|
|withCRLF|normal
+--------+-------+

我们看到我们已经解决了"\n“的问题,但没有解决”\r“的问题。因此,如果您确实希望在搜索/替换中使用正则表达式,则应该同时声明CR和LF将被替换:

代码语言:javascript
复制
scala> dataframe.withColumn("value", regexp_replace($"value", "[\r\n]+", " ")).show
+--------+-------+
|      id|  value|
+--------+-------+
|  normal| normal|
|  withLF|normal |
|withCRLF|normal |
+--------+-------+

(可能的增强: de不使用regexp来替换单个字符。不要输出输出字符串末尾的空白字符,.)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52038810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档