PIG UDF (Python) 字符集编码
Posted
技术标签:
【中文标题】PIG UDF (Python) 字符集编码【英文标题】:PIG UDF (Python) Charset Encoding 【发布时间】:2015-02-23 16:30:13 【问题描述】:我是编写 Python 和 Pig UDF 的初学者,并且正在努力使用 PIG 对输入文件进行字符集转换。
浏览***和整个互联网几天,尝试了很多不同的东西,但我仍然无助。
希望有人可以轻轻推动我朝着正确的方向前进。
环境:真正的分布式 Hadoop 集群(无本地实例)/Cloudera 配置有utf-8
和Apache Pig version 0.12.0
我的源文件使用iso-8859-1
编码,目标是将其内容存储为utf-8
(在pig 中的其他几个操作之后或之前)。
输入文件如下所示(几个 ASCII/iso-8859-1 字符用于测试目的 - 每行一个字符):
ù
û
ü
ÿ
à
â
æ
ç
é
è
ê
ë
î
ô
这是我的猪脚本:
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 ***: Encoding in Pig - Java solution)?
非常感谢您的任何建议。
【问题讨论】:
【参考方案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 中的等效数据类型
希望对你有帮助
【讨论】:
【参考方案2】:以下是用 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
这里是用于注册 UDF、加载数据、将 UDF 应用于数据以及获取该数据的样本以检查解码是否按预期工作的 PIG 命令。
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 在他的回答中提到的,这里的重要部分是将您的字段定义为字节数组。
【讨论】:
以上是关于PIG UDF (Python) 字符集编码的主要内容,如果未能解决你的问题,请参考以下文章