簡體   English   中英

PySpark — UnicodeEncodeError: 'ascii' 編解碼器無法編碼字符

[英]PySpark — UnicodeEncodeError: 'ascii' codec can't encode character

使用spark.read.csv帶有外來字符 (åäö) 的數據幀加載到 Spark 中,使用encoding='utf-8'並嘗試執行簡單的 show()。

>>> df.show()

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/spark/python/pyspark/sql/dataframe.py", line 287, in show
print(self._jdf.showString(n, truncate))
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 579: ordinal not in range(128)

我認為這可能與 Python 本身有關,但我無法理解此處提到的任何技巧如何應用於 PySpark 和 show() 函數的上下文中。

https://issues.apache.org/jira/browse/SPARK-11772談到了這個問題並給出了一個運行的解決方案:

export PYTHONIOENCODING=utf8

在運行pyspark之前。 我想知道為什么上面有效,因為sys.getdefaultencoding()即使沒有它也會為我返回utf-8

如何在 Python 3 中設置 sys.stdout 編碼? 還談到了這一點,並為 Python 3 提供了以下解決方案:

import sys
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf8', buffering=1)
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

這對我有用,我預先設置了編碼並且它在整個腳本中都是有效的。

我在使用以下版本的 Spark 和 Python 時遇到了同樣的問題:

火花 - 2.4.0

Python - 2.7.5

以上解決方案都不適合我。

對我來說,問題是在嘗試將結果 RDD 保存到 HDFS 位置時發生的。 我從 HDFS 位置獲取輸入並將其保存到 HDFS 位置。 以下是出現此問題時用於讀寫操作的代碼:

讀取輸入數據:

monthly_input = sc.textFile(monthly_input_location).map(lambda i: i.split("\x01"))
monthly_input_df = sqlContext.createDataFrame(monthly_input, monthly_input_schema)

寫入 HDFS:

result = output_df.rdd.map(tuple).map(lambda line: "\x01".join([str(i) for i in line]))
result.saveAsTextFile(output_location)

我把讀寫代碼分別改成了下面的代碼:

閱讀代碼:

monthly_input = sqlContext.read.format("csv").option('encoding', 'UTF-8').option("header", "true").option("delimiter", "\x01").schema(monthly_input_schema).load(monthly_input_location)

編寫代碼:

output_df.write.format('csv').option("header", "false").option("delimiter", "\x01").save(output_location)

這不僅解決了問題,而且大大提高了 IO 性能(近 3 倍)。

但是在使用上述寫入邏輯時存在一個已知問題,我還沒有找到合適的解決方案。 如果輸出中有空白字段,由於 CSV 編碼,它將顯示用雙引號 ("") 括起來的空白值。

對我來說,這個問題目前不是什么大問題。 無論如何,我正在將輸出加載到配置單元,並且在導入時可以刪除雙引號。

PS:我還在使用 SQLContext。 尚未升級到 SparkSession。 但是到目前為止,我在基於 SparkSession 的代碼中嘗試過的類似讀寫操作也將類似地工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM