13

我想对列的子集执行 DISTINCT 操作。文档说这可以通过嵌套的 foreach 实现:

您不能在字段子集上使用 DISTINCT;为此,请使用 FOREACH 和嵌套块首先选择字段,然后应用 DISTINCT(请参阅示例:嵌套块)。

对所有列执行 DISTINCT 操作很简单:

A = LOAD 'data' AS (a1,a2,a3,a4);
A_unique = DISTINCT A;

假设我有兴趣在 a1、a2 和 a3 上执行不同的操作。谁能提供一个示例,说明如何按照文档中的建议使用嵌套的 foreach 执行此操作?

这是输入和预期输出的示例:

A = LOAD 'data' AS(a1,a2,a3,a4);
DUMP A;

(1 2 3 4)
(1 2 3 4)
(1 2 3 5)
(1 2 4 4)

-- insert DISTINCT operation on a1,a2,a3 here:
-- ...

DUMP A_unique;

(1 2 3 4)
(1 2 4 4)
4

6 回答 6

21

对所有其他列进行分组,仅将感兴趣的列投影到一个包中,然后使用FLATTEN再次展开它们:

A_unique =
    FOREACH (GROUP A BY a4) {
        b = A.(a1,a2,a3);
        s = DISTINCT b;
        GENERATE FLATTEN(s), group AS a4;
    };
于 2013-09-25T23:34:48.693 回答
2

接受的答案是一个很好的解决方案,但如果您想重新排序输出中的字段(我最近必须做的事情),这可能不起作用。这是一个替代方案:

A = LOAD '$input' AS (f1, f2, f3, f4, f5);
GP = GROUP A BY (f1, f2, f3);
OUTPUT = FOREACH GP GENERATE 
    group.f1, group.f2, f4, f5, group.f3 ;

当您对某些字段进行分组时,选择将在每个元组中具有该组的唯一值。

于 2015-02-13T10:45:50.747 回答
1

对于您指定的输入/输出,以下工作。您可能会更新您的测试向量以澄清您需要的与此不同的内容。

A_unique = DISTINCT A;
于 2014-01-18T13:41:28.027 回答
0

这里有2个可能的解决方案,还有其他好的方法吗?

解决方案 1(使用 LIMIT 1):

A = LOAD 'test_data' AS (a1,a2,a3,a4);

-- Combine the columns that I want to perform the distinct across into a tuple
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4

-- Group by the combined column
grouped_by_a4 = GROUP A2 BY combined;

grouped_and_distinct = FOREACH grouped_by_a4 {
        single = LIMIT A2 1;
        GENERATE FLATTEN(single);
};

解决方案 2(使用 DISTINCT):

A = LOAD 'test_data' AS (a1,a2,a3,a4);

-- Combine the columns that I want to perform the distinct across into a tuple
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4

-- Group by the other columns (those I don't want the distinct applied to)
grouped_by_a4 = GROUP A2 BY a4;

-- Perform the distinct on a projection of combined and flatten 
grouped_and_distinct = FOREACH grouped_by_a4 {
        combined_unique = DISTINCT A2.combined;
        GENERATE FLATTEN(combined_unique);
};
于 2013-09-25T23:34:01.030 回答
0
unique_A = FOREACH (GROUP A BY (a1, a2, a3)) {
    limit_a = LIMIT A 1;
    GENERATE FLATTEN(limit_a) AS (a1,a2,a3,a4);
};
于 2016-02-24T01:17:36.153 回答
0

我也想做同样的事情:“我想对列的子集执行 DISTINCT 操作”。我这样做的方式是:

A = LOAD 'data' AS(a1,a2,a3,a4);
interested_fields = FOREACH A GENERATE a1,a2,a3;
distinct_fields= DISTINCT interested_fields;
final_answer = FOREACH distinct_fields GENERATE FLATTEN($0);

我知道这不是文档中建议的如何执行嵌套 foreach 的示例;但这是一种对字段子集进行区分的方法。希望它对像我一样到达这里的人有所帮助。

于 2020-04-07T01:39:18.887 回答