从 python UDF 返回未知长度的元组,然后在 Pig 中应用散列
Returning tuple of unknown length from python UDF and then applying hash in Pig
这个问题有两部分:
首先,我有一个 python UDF,它创建一个未知长度的字符串列表。 UDF 的输入是 map
(python 中的 dict
),键的数量基本上是未知的(这是我想要获得的)。
我不知道如何在模式中输出它 return 它作为列表(或其他一些可迭代的数据结构)。这是我目前所拥有的:
@outputSchema("?????") #WHAT SHOULD THE SCHEMA BE!?!?
def test_func(input):
output = []
for k, v in input.items():
output.append(str(key))
return output
现在,问题的第二部分。进入 Pig 后,我想为所有用户对 "list" 中的每个元素应用一个 SHA 散列。一些 Pig 伪代码:
USERS = LOAD 'something' as (my_map:map[chararray])
UDF_OUT = FOREACH USERS GENERATE my_udfs.test_func(segment_map)
SHA_OUT = FOREACH UDF_OUT GENERATE SHA(UDF_OUT)
最后一行可能有误,因为我想将 SHA 应用于列表中的每个元素,而不是整个列表。
为了回答你的问题,因为你要返回一个 python 列表,其内容是一个字符串,你会希望你的装饰器是
@outputSchema('name_of_bag:{(keys:chararray)}')
指定此结构时可能会造成混淆,因为您只需要定义包中 一个 元素的外观。
话虽这么说,但有一种更简单的方法可以满足您的要求。有一个函数 KEYSET()
(You can reference this question I answered) 可以从 Pig Map 中提取键。因此,使用该示例中的数据集并向第一个添加更多键,因为您说地图内容的长度是可变的
maps
----
[a#1,b#2,c#3,d#4,e#5]
[green#sam,eggs#I,ham#am]
查询:
REGISTER /path/to/jar/datafu-1.2.0.jar;
DEFINE datafu.pig.hash.SHA();
A = LOAD 'data' AS (M:[]);
B = FOREACH A GENERATE FLATTEN(KEYSET(M));
hashed = FOREACH B GENERATE [=12=], SHA([=12=]);
DUMP hashed;
输出:
(d,18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4)
(e,3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea)
(b,3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d)
(c,2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6)
(a,ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb)
(ham,eccfe263668d171bd19b7d491c3ef5c43559e6d3acf697ef37596181c6fdf4c)
(eggs,46da674b5b0987431bdb496e4982fadcd400abac99e7a977b43f216a98127721)
(green,ba4788b226aa8dc2e6dc74248bb9f618cfa8c959e0c26c147be48f6839a0b088)
这个问题有两部分:
首先,我有一个 python UDF,它创建一个未知长度的字符串列表。 UDF 的输入是 map
(python 中的 dict
),键的数量基本上是未知的(这是我想要获得的)。
我不知道如何在模式中输出它 return 它作为列表(或其他一些可迭代的数据结构)。这是我目前所拥有的:
@outputSchema("?????") #WHAT SHOULD THE SCHEMA BE!?!?
def test_func(input):
output = []
for k, v in input.items():
output.append(str(key))
return output
现在,问题的第二部分。进入 Pig 后,我想为所有用户对 "list" 中的每个元素应用一个 SHA 散列。一些 Pig 伪代码:
USERS = LOAD 'something' as (my_map:map[chararray])
UDF_OUT = FOREACH USERS GENERATE my_udfs.test_func(segment_map)
SHA_OUT = FOREACH UDF_OUT GENERATE SHA(UDF_OUT)
最后一行可能有误,因为我想将 SHA 应用于列表中的每个元素,而不是整个列表。
为了回答你的问题,因为你要返回一个 python 列表,其内容是一个字符串,你会希望你的装饰器是
@outputSchema('name_of_bag:{(keys:chararray)}')
指定此结构时可能会造成混淆,因为您只需要定义包中 一个 元素的外观。
话虽这么说,但有一种更简单的方法可以满足您的要求。有一个函数 KEYSET()
(You can reference this question I answered) 可以从 Pig Map 中提取键。因此,使用该示例中的数据集并向第一个添加更多键,因为您说地图内容的长度是可变的
maps
----
[a#1,b#2,c#3,d#4,e#5]
[green#sam,eggs#I,ham#am]
查询:
REGISTER /path/to/jar/datafu-1.2.0.jar;
DEFINE datafu.pig.hash.SHA();
A = LOAD 'data' AS (M:[]);
B = FOREACH A GENERATE FLATTEN(KEYSET(M));
hashed = FOREACH B GENERATE [=12=], SHA([=12=]);
DUMP hashed;
输出:
(d,18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4)
(e,3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea)
(b,3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d)
(c,2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6)
(a,ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb)
(ham,eccfe263668d171bd19b7d491c3ef5c43559e6d3acf697ef37596181c6fdf4c)
(eggs,46da674b5b0987431bdb496e4982fadcd400abac99e7a977b43f216a98127721)
(green,ba4788b226aa8dc2e6dc74248bb9f618cfa8c959e0c26c147be48f6839a0b088)