Apache spark 在pyspark中使用多分隔符读取数据
我有一个输入文件,它看起来像这样,并且有Apache spark 在pyspark中使用多分隔符读取数据,apache-spark,pyspark,ascii,delimiter-separated-values,Apache Spark,Pyspark,Ascii,Delimiter Separated Values,我有一个输入文件,它看起来像这样,并且有“|”作为多分隔符: 162300111000000000106779"|"2005-11-16 14:12:32.860000000"|"1660320"|"0"|"2005-11-16 14:12:32.877000000"|""|""|""|""|""|""|""|"False"|"120600111000000000106776``` 我可以通过自定义项读取此类记录,如下所示: inputDf = glueContext.sparkSession
“|”
作为多分隔符:
162300111000000000106779"|"2005-11-16 14:12:32.860000000"|"1660320"|"0"|"2005-11-16 14:12:32.877000000"|""|""|""|""|""|""|""|"False"|"120600111000000000106776```
我可以通过自定义项读取此类记录,如下所示:
inputDf = glueContext.sparkSession.read.option("delimiter", input_file_delimiter,)
.csv("s3://" + landing_bucket_name + "/" + input_file_name)
udf = UserDefinedFunction(lambda x: re.sub('"', '', str(x)))
new_df = inputDf.select(*[udf(column).alias(column) for column in inputDf.columns])
但是当我把输入文件作为
000/00"|"AE71501"|"Complaint for Attachment of Earnings Order"|"In accordance with section test of the Attachment of Test Act Test."|"Non-Test"|"Other non-test offences"|"N"|"Other Non-Test"|"Non-Test
我在阅读时遇到以下异常,使用相同的UDF,我的代码在使用mu UDF的同一位置失败:
UnicodeEncodeError:“ascii”编解码器无法对位置66中的字符u'\xfa'进行编码:序号不在范围内(128)
下面的任何帮助都将非常有用:
-优化代码以读取这两种类型的文件,将“|”
作为分隔符。
-我现有的UDF如何处理第二种类型的输入记录。这可能是由于在Python2.x中运行造成的,Python2.x对类似字符串的对象有两种不同的类型(unicode字符串和非unicode字符串,它们现在只是字节序列) Spark将读取您的数据(数据是字节,因为没有纯文本),并将行解码为Unicode字符串序列。当对具有不在ASCII码点范围内的码点的Unicode字符串调用
str
时,Python 2将产生错误:
#python2.7>>unicode_str=u“ú”
>>>类型(unicode_str)
>>>str(unicode_str)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
UnicodeEncodeError:“ascii”编解码器无法对位置0中的字符u'\xfa'进行编码:序号不在范围内(128)
建议您在整个程序中使用Unicode字符串(这是Python 3中的默认字符串对象),但在读取/接收数据(应提供适当的编码方案,以便对原始字节进行解码)和写入/发送数据时除外(同样,使用编码将数据编码为一系列字节)。这称为“”
包括Spark在内的许多库已经为您解码字节和编码unicode字符串。如果您只需删除用户定义函数中对str
的调用,您的代码可能会正常工作:
使用Python 2.7的pyspark shell
>>>spark.sparkContext.setLogLevel(“OFF”)#隐藏转储到控制台的大Py4J回溯,而不修改log4j.properties文件
>>>从py4j.protocol导入Py4JJavaError
>>>从pyspark.sql.types导入*
>>>从pyspark.sql.functions导入udf
>>>df=spark.read.csv(“您的_文件.csv”,sep=“|”)
>>>转换后的def带双引号:
…进口稀土
…返回re.sub(“,”,str(s))
...
>>>def带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号带双引号
…进口稀土
…返回re.sub(“,”,s)
...
>>>df.select(*[udf(不带str转换的带双引号,StringType())(column).df.columns中列的别名(column)).show()
+------+-------+--------------------+--------------------+--------------------+----------------+---+--------------------+----+
|_c0 | uC1 | uC2 | uC3 | uC4 | uC5 | uC6 | uC7 | uC8|
+------+-------+--------------------+--------------------+--------------------+----------------+---+--------------------+----+
|037/02 | TH68150 |加重驾驶车辆|与第i节|盗窃机动车|车辆犯罪| Y |加重驾驶车辆| 37.2相反|
+------+-------+--------------------+--------------------+--------------------+----------------+---+--------------------+----+
>>>尝试:
…df.select(*[udf(str转换后的带双引号,StringType())(column).df.columns中列的别名(column)).show()
…除了Py4JJavaError作为e:
…打印(“失败。根本原因:%s”%e.java_exception.getCause().getMessage().rsplit(“\n”,2)[-2])
...
失败。根本原因:UnicodeEncodeError:“ascii”编解码器无法对78位的字符u'\xfa'进行编码:序号不在范围内(128)
因此,有经验问题的解决方案很简单:不要在UDF中使用str
请注意,从2020年1月1日起,Python 2.x将不再被维护。在此之前,您最好过渡到Python 3.x。事实上,如果您在Python 3解释器中执行此操作,您将不会遇到任何问题。我怀疑错误是由您的想法产生的。stacktrace说这与t有关Unicode符号u'\xfa',是ú,在您显示的内容中不存在。我有一个非常大的文件,可以在该文件中的某个位置。Saldy,我们无法用您提供的数据重现您的问题。您能生成一个最小的数据集,让我们可以这样做吗?