pig udf(python)字符集编码

iyr7buue  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(379)

我是编写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解决方案中的编码)?
非常感谢您的建议。

7qhs6swi

7qhs6swi1#

我在解决一个类似的问题。是的,字符编码在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。
也就是说,您的自定义项应该保持不变,但是输入需要在pig中更改为tobytearray,在您的自定义项中更改为等效的数据类型
希望这有帮助

7vux5j2d

7vux5j2d2#

下面是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在回答中提到的,这里的重要部分是将字段定义为字节数组。

相关问题