我试图使用Scala中的foldLeft & regex_replace从Dataframe的字符串列中删除新的行字符。在读取了postgres上的关系数据库管理系统表: public.test_sid之后创建了数据。该表有4列:id, id1, id2, id3和id3中有一个新的行字符。我就是这样写逻辑的:
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的输出日志中,我看到了插入的格式的数据。
+--------------------+--------------------+----+---+
| id| id1| id2|id3|
+--------------------+--------------------+----+---+
|1.000000000000000000|1.000000000000000000| a|
a|
+--------------------+--------------------+----+---+但是finalDF中的数据以一种奇怪的格式显示出来。最后一列: id3的值出现在dataframe的开头,第一列的第一个数字: id被截断并表示为'000000000000000000‘而不是'1.000000000000000000’。
+--------------------+--------------------+----+---+
| id| id1| id2|id3|
+--------------------+--------------------+----+---+
a|000000000000000000|1.000000000000000000| a|
+--------------------+--------------------+----+---+列的数据:id3优先
如果我只是从id3访问特定的列: finalDF,我将得到如下数据:
scala> finalDF.select(finalDF("id3")).show
+---+
|id3|
+---+
a|
+---+
scala> finalDF.select(finalDF("id")).show
+--------------------+
| id|
+--------------------+
|1.000000000000000000|
+--------------------+这只是打印数据时的控制台问题,还是代码中存在缺陷?如果我上面写的代码有什么问题,有人能告诉我吗?
发布于 2018-08-27 12:30:51
看起来像个CRLF。\r)问题。
历史上,一个用来告诉控制台在行的开头返回,另一个用来创建一个新的行。
在这里,你似乎抑制了新行的创建,但仍然有“回到起点”的部分。
因此,我建议您将替换为 \r和\n。
请参阅CR上的维基百科
回车,有时称为盒式回车,通常缩短为CR,或返回,是一种控制字符或机制,用于将设备的位置重置到一行文本的开头。它与行提要和换行符概念密切相关,尽管它本身可以单独考虑。
要查看它的运行情况,让我们创建一个测试数据文件:
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”的字符串有您在帖子开始时观察到的问题。现在,如果我使用您替换函数:
dataframe.withColumn("value", regexp_replace($"value", "\n", "")).show
+--------+-------+
| id| value|
+--------+-------+
| normal| normal|
| withLF| normal|
|withCRLF|normal
+--------+-------+我们看到我们已经解决了"\n“的问题,但没有解决”\r“的问题。因此,如果您确实希望在搜索/替换中使用正则表达式,则应该同时声明CR和LF将被替换:
scala> dataframe.withColumn("value", regexp_replace($"value", "[\r\n]+", " ")).show
+--------+-------+
| id| value|
+--------+-------+
| normal| normal|
| withLF|normal |
|withCRLF|normal |
+--------+-------+(可能的增强: de不使用regexp来替换单个字符。不要输出输出字符串末尾的空白字符,.)。
https://stackoverflow.com/questions/52038810
复制相似问题