【求解】pyspark中文编码问题怎么解决?

最近使用python-spark遇到一个无法解决的中文编码问题。

查了网上的资料和解决方法,都无法使之解决。

不知道哪位大佬可以帮忙指点一二?

问题摘要,python使用UTF8编码,spark使用的是ascii编码,处理中文文件时遇到乱码问题。


情形1、读取本地文件创建DataFrame时的中文编码问题

#in python

import codecs
local_file = "a_local_file.csv"
cate_list = []

for line in open(local_file, "r"):
	line = line.strip()
	line = line.replace(codecs.BOM_UTF8, "")
	arr = line.split(',')
	if len(arr) < 3:
		continue
	else:
		tier2_name = arr[0]
		tier3_name = arr[1]
		tier3_code = int(arr[2])
		cate_list.append((tier3_code, tier3_name, tier2_name))
df_cate = spark.createDataFrame(cate_list,
						["third_cate_code","third_cate_name","second_cate_name"])
df_cate.cache()
df_cate.createOrReplaceTempView("cate_codes")
df_cate.show()

show的结果:【如显示,中文全是乱码!!!

 

情形2: spark自定义函数UDF时的中文乱码问题

第一步:定义并注册两个UDF,将code转成其中文名称

#in python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time: 2021/04/19 20:20 上午
# @Author: gao
#pyspark

import os, sys, datetime, time
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def regist_bin_udf(spark):
	#将配置文件读入并获取配置信息
	import codecs
	local_file = "a_local_file.csv"
	data_dict = {}
	for line in open(local_file, "r"):
		line = line.strip()
		line = line.replace(codecs.BOM_UTF8,"")
		arr = line.split(',')
		if len(arr) < 3:
			continue
		else:
			tier2_name = arr[0]
			tier3_name = arr[1]
			tier3_code = int(arr[2])
			data_dict[tier3_code] = {}
			data_dict[tier3_code]["tier2_name"] = tier2_name
			data_dict[tier3_code]["tier3_name"] = tier3_name

	#写UDF获取二级类目的名称
	def tier2_name(tier3):
		if tier3 in data_dict.keys():
			name = data_dict[int(tier3)]["tier2_name"]
		else:
			name = 'NaN'
		return name
	spark.udf.register("tier2_name",tier2_name)

	# 写UDF获取三级类目的名称
	def tier3_name(tier3):
		if tier3 in data_dict.keys():
			name = data_dict[int(tier3)]["tier3_name"]
		else:
			name = 'NaN'
		return name

	spark.udf.register("tier3_name", tier3_name)

第二步:调用UDF,获取中文名称

#in python
sql_string = """
			SELECT
			    encode(decode(tier3_name(third_cate_code),'utf-8'), 'ascii') as third_cate_name,
				tier2_name(third_cate_code) as second_cate_name,
			FROM
				your_table_name
			 WHERE
				dt = '{day_begin}'
				AND third_cate_code IN {third_cate_codes}
        """.format(day_begin=day_begin,third_cate_codes=third_cate_codes)
sys.stderr.write(sql_string)
spark.sql(sql_string)

第三步:查看结果 【中文名称都是乱码!!!】

3、尝试过的方法

尝试过以下方法,然而并没有卵用~!!!

3.1 声明utf-8编码

reload(sys)
sys.setdefaultencoding('utf-8')

3.2 情形一中读取本地文件时,使用.decode("utf-8").encode("ascii")重新编码

#in python
		tier2_name = arr[0].encode("ascii")
		tier3_name = arr[1].decode("utf-8").encode("ascii")

3.3 情形二中读取本地文件,定义UDF时,使用.decode("utf-8").encode("ascii")重新编码

改动的代码同3.2

3.4 情形二中spark.sql时,使用encode(decode(,),) 重新编码

select
encode(decode(tier3_name(third_cate_code),'utf-8'), 'ascii') as third_cate_name,
tier2_name(third_cate_code) as second_cate_name
from
...

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值