Python Spark - 在 parquet 文件中转义引号
Python Spark - Escaping quotes in parquet file
我的镶木地板文件是从 CSV 派生的,其中一些单元格被转义了。例如:这是一个值
"a , ""Hello"" c"
我希望 parquet 将其读取为
a , "Hello" c
我在阅读时试图从 parquet 文件中转义引号。
如果我正在阅读 CSV,我可以按以下方式进行
df = spark.read.option('quote', '"').
option('escape', '"').csv("./temp.csv")
但是,对于 parquet 文件,我们没有类似的东西。我读过使用选项和不使用选项的镶木地板
>>> dfP = spark.read.parquet("./temp.parquet")
>>> dfP.show()
+---+---+---+----------------+---+
|_c0|_c1|_c2| _c3|_c4|
+---+---+---+----------------+---+
| A| B| C| D| E|
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
>>> dfP = spark.read.option('quote', '"').
option('escape', '"').parquet("./temp.parquet")
>>> dfP.show()
+---+---+---+----------------+---+
|_c0|_c1|_c2| _c3|_c4|
+---+---+---+----------------+---+
| A| B| C| D| E|
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
我希望将 D 列读作 'a, "Hello" c'。
有什么办法让它起作用吗?
输入的 parquet 是从
的 CSV 文件转换而来的
A,B,C,D,E
1,2,"3,4","a, ""HEllo"" c",5
编辑:Parquet 已经生成。我无法更改镶木地板的生成方式。我必须使用我得到的拼花地板并尝试逃脱。
据我所知,镶木地板文件只有一个选项。它用于压缩。 'quote'、'delimiter'、'escape' 等其他选项适用于 csv 文件。所以它们不适用于镶木地板文件。
我试着模拟了你的案例,我认为这个案例的最佳解决方案是使用函数。首先,我创建了一个 csv 文件并将其放入 HDFS
[ali@aliyesilli ~]$ hadoop fs -cat /test/exCsv/test.csv
A,B,C,D,E
1,2,"3,4","a, ""HEllo"" c",5
然后我将其读取为 csv 文件并再次将其保存为 parquet 文件
>>> df = spark.read.csv('hdfs://localhost:8020/test/exCsv',header=True)
>>> df.show()
+---+---+---+----------------+---+
| A| B| C| D| E|
+---+---+---+----------------+---+
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
>>> df.write.parquet('hdfs://localhost:8020/test/exPar')
当我尝试读取 parguet 文件时,D 列包含您提到的双引号
>>> spark.read.parquet('hdfs://localhost:8020/test/exPar').show()
+---+---+---+----------------+---+
| A| B| C| D| E|
+---+---+---+----------------+---+
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
然后我定义了一个名为 strip 的函数,并将它与 regexp_replace 函数一起使用来创建你想看到的字符串
>>> import pyspark.sql.functions as func
>>> strip=func.udf(lambda x: x.strip('"'))
>>>
>>> spark.read.parquet('hdfs://localhost:8020/test/exPar').withColumn('D', func.regexp_replace(strip('D'), '""', '"')).show()
+---+---+---+------------+---+
| A| B| C| D| E|
+---+---+---+------------+---+
| 1| 2|3,4|a, "HEllo" c| 5|
+---+---+---+------------+---+
也许还有其他不同的解决方案,但在这种情况下,我认为您应该使用 udf 或 sql 函数
我的镶木地板文件是从 CSV 派生的,其中一些单元格被转义了。例如:这是一个值
"a , ""Hello"" c"
我希望 parquet 将其读取为
a , "Hello" c
我在阅读时试图从 parquet 文件中转义引号。 如果我正在阅读 CSV,我可以按以下方式进行
df = spark.read.option('quote', '"').
option('escape', '"').csv("./temp.csv")
但是,对于 parquet 文件,我们没有类似的东西。我读过使用选项和不使用选项的镶木地板
>>> dfP = spark.read.parquet("./temp.parquet")
>>> dfP.show()
+---+---+---+----------------+---+
|_c0|_c1|_c2| _c3|_c4|
+---+---+---+----------------+---+
| A| B| C| D| E|
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
>>> dfP = spark.read.option('quote', '"').
option('escape', '"').parquet("./temp.parquet")
>>> dfP.show()
+---+---+---+----------------+---+
|_c0|_c1|_c2| _c3|_c4|
+---+---+---+----------------+---+
| A| B| C| D| E|
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
我希望将 D 列读作 'a, "Hello" c'。 有什么办法让它起作用吗?
输入的 parquet 是从
的 CSV 文件转换而来的A,B,C,D,E
1,2,"3,4","a, ""HEllo"" c",5
编辑:Parquet 已经生成。我无法更改镶木地板的生成方式。我必须使用我得到的拼花地板并尝试逃脱。
据我所知,镶木地板文件只有一个选项。它用于压缩。 'quote'、'delimiter'、'escape' 等其他选项适用于 csv 文件。所以它们不适用于镶木地板文件。
我试着模拟了你的案例,我认为这个案例的最佳解决方案是使用函数。首先,我创建了一个 csv 文件并将其放入 HDFS
[ali@aliyesilli ~]$ hadoop fs -cat /test/exCsv/test.csv
A,B,C,D,E
1,2,"3,4","a, ""HEllo"" c",5
然后我将其读取为 csv 文件并再次将其保存为 parquet 文件
>>> df = spark.read.csv('hdfs://localhost:8020/test/exCsv',header=True)
>>> df.show()
+---+---+---+----------------+---+
| A| B| C| D| E|
+---+---+---+----------------+---+
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
>>> df.write.parquet('hdfs://localhost:8020/test/exPar')
当我尝试读取 parguet 文件时,D 列包含您提到的双引号
>>> spark.read.parquet('hdfs://localhost:8020/test/exPar').show()
+---+---+---+----------------+---+
| A| B| C| D| E|
+---+---+---+----------------+---+
| 1| 2|3,4|"a, ""HEllo"" c"| 5|
+---+---+---+----------------+---+
然后我定义了一个名为 strip 的函数,并将它与 regexp_replace 函数一起使用来创建你想看到的字符串
>>> import pyspark.sql.functions as func
>>> strip=func.udf(lambda x: x.strip('"'))
>>>
>>> spark.read.parquet('hdfs://localhost:8020/test/exPar').withColumn('D', func.regexp_replace(strip('D'), '""', '"')).show()
+---+---+---+------------+---+
| A| B| C| D| E|
+---+---+---+------------+---+
| 1| 2|3,4|a, "HEllo" c| 5|
+---+---+---+------------+---+
也许还有其他不同的解决方案,但在这种情况下,我认为您应该使用 udf 或 sql 函数