PIG UDF(Python)字符集编码

3

我是一个Python和Pig UDF编写的初学者,在使用PIG时遇到了输入文件的字符集转换问题。

我在StackOverflow和整个互联网上搜索了几天,尝试了很多不同的方法,但我仍然无助。

希望有人能给我指点一下方向。


环境:真实分布式Hadoop集群(没有本地实例)/ Cloudera配置为utf-8Apache Pig版本0.12.0

我的源文件以iso-8859-1编码,目标是将其内容存储为utf-8(在pig中进行其他操作之前或之后)。

输入文件看起来像这样(为测试目的而包含几个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();

我的UDF(用Python编写)如下所示:

#!/usr/bin/env python
# charsetConversion.py

@outputSchema("word:chararray")
def toUTF8(s):
    return unicode(s, 'iso-8859-1').encode('utf-8')

运行/提交脚本后,我得到了以下输出:

� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �
� �

在第二列中,我希望看到与输入文件中相同的易读值,而不是 �
这是怎么回事?
我的方法是否可行?
还有哪些其他方法可以使用(不需要使用Java,参见Stackoverflow: Encoding in Pig - Java solution)?
非常感谢您提前的帮助和任何建议。
2个回答

1
我曾经解决过类似的问题。 是的,在Java/Hadoop世界中,字符编码可能会很棘手:)。
实际上,你已经非常接近答案了 - 解决方案是:
data = LOAD '$input' USING PigStorage() AS (col1:bytearray);

问题在于您将col1指定为chararray。Chararray是“Unicode UTF-8格式的数组(字符串)”。然而,您的输入数据不是如此,这些数据是iso-8859-1格式的。Pig脚本将您的数据解释为UTF-8,而不是iso-8859-1。您应该改为指定bytearray。Bytearray不会以任何方式解释数据 - 您必须自行处理数据(例如,在UDF函数中)。

接下来,我们需要处理每一行:

parsed = foreach a generate flatten(my.testparser($0));

然后,在UDF函数(my.testparser())中,我们将把iso-8859-1编码更改为utf-8

  ....
  val line:String = input.get(0).asInstanceOf[DataByteArray].get(), "windows-1250")
  ....

代码是用Scala编写的(我不是Python专家-抱歉),它接受输入DataByteArray(在PIG中为bytearray),并获取Scala.Bytes数组。这些字节随后被解释为windows-1250。

也就是说,您的UDF应该保持不变,但输入需要更改为Pig中的bytearray和UDF中的等效数据类型。

希望这可以帮助到您。


1

以下是我在Python中定义的UDF,适用于那些不熟悉Scala的人:

#!/usr/bin/env python
# charsetConversion.py
import struct

@outputSchema("word:chararray")
def toUTF8(s):
        line = ‘.’join([struct.pack(‘B’, x).decode(‘iso-8859-1’) for x in s])
        return line

以下是PIG命令,用于注册UDF、加载数据、将UDF应用于数据,并获取该数据的样本以检查解码是否按预期工作。
REGISTER 'charsetConversion.py' USING org.apache.pig.scripting.jython.JythonScriptEngine AS pyudf;
data = LOAD '$input' USING TextLoader AS (col1: bytearray);
final = FOREACH data GENERATE $0,pyudf.toUTF8(col1);
final_lim = LIMIT final 10;
DUMP final_lim;

正如xhudik在他的答案中提到的,这里重要的部分是将您的字段定义为字节数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接