我是编写python和pig-udf的初学者,正在努力使用pig进行输入文件的字符集转换。
浏览了好几天的stackoverflow和整个互联网,尝试了很多不同的东西,但我还是很无助。
希望有人能轻轻地把我推向正确的方向。
环境:一个真正的分布式hadoop集群(没有本地示例)/cloudera配置 utf-8
以及 Apache Pig version 0.12.0
我的源文件是用 iso-8859-1
目标是将其内容存储为 utf-8
(在清管器内的其他几次操作之后或之前)。
输入文件如下所示(出于测试目的,有两个ascii/iso-8859-1字符-每行一个字符):
ù
û
ü
ÿ
à
â
æ
ç
é
è
ê
ë
î
ô
这是我的Pig剧本:
RMF $output;
REGISTER 'charsetConversion.py' using org.apache.pig.scripting.jython.JythonScriptEngine AS pyudf;
data = LOAD '$input' USING PigStorage() AS (col1:chararray); --col1:bytearray
final = foreach data generate $0, pyudf.toUTF8(col1);
STORE final INTO '$output' USING PigStorage();
以及我的自定义项(用python编写):
# !/usr/bin/env python
# charsetConversion.py
@outputSchema("word:chararray")
def toUTF8(s):
return unicode(s, 'iso-8859-1').encode('utf-8')
运行/提交脚本后,我得到以下输出:
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
在第二列中,我期望与输入文件中的可读值相同,而不是相同的值 �
.
这里发生了什么?
我的方法是否值得推荐?
还有什么其他的方法(没有JavaStackOverflow:pig-java解决方案中的编码)?
非常感谢您的建议。
2条答案
按热度按时间7qhs6swi1#
我在解决一个类似的问题。是的,字符编码在java/hadoop中可能很棘手:)。
实际上,你已经很接近了-解决办法是:
问题是您将col1指定为chararray。chararray是“unicode utf-8格式的数组(字符串)”。但是,这对于iso-8859-1中的输入数据是不正确的。pig脚本将您的数据解释为utf-8而不是iso-8859-1。您应该改为指定bytearray。bytearray不以任何方式解释数据-您必须这样做(例如在您的udf函数中)。
在下一行中,我们需要处理每一行:
然后,在udf函数(my.testparser())中,我们将iso-8859-1编码更改为utf-8:
代码是用scala编写的(对不起,我不是python的人),它需要输入databytearray(pig中的bytearray)并获取scala.bytes的数组。这些字节被解释为windows-1250。
也就是说,您的自定义项应该保持不变,但是输入需要在pig中更改为tobytearray,在您的自定义项中更改为等效的数据类型
希望这有帮助
7vux5j2d2#
下面是python中定义的udf,对于那些不熟悉scala的人来说,它对我很有用:
以下是pig命令,用于注册udf、加载数据、对数据应用udf,并获取该数据的样本,以检查解码是否按预期工作。
正如xhudik在回答中提到的,这里的重要部分是将字段定义为字节数组。