如何获取将为我提供Pyspark Dataframe中唯一记录的列列表

时间:2019-06-27 18:37:16

标签: apache-spark pyspark apache-spark-sql

我的目的是编写一个python函数,该函数将pyspark DataFrame用作输入,并且其输出将是列的列表(可以是多个列表),当组合在一起时会给出唯一的记录。

因此,如果您为列表中的列取一组值,则始终只会从DataFrame中获得1条记录。

示例: 输入数据框

Name    Role    id
--------------------
Tony    Dev     130
Stark   Qa      131
Steve   Prod    132
Roger   Dev     133
--------------------

输出:

Name,Role
Name,id 
Name,id,Role

为什么输出是什么? 对于任何Name,Role组合,我将始终仅获得1条记录 而且,对于任何名称,id组合,我总是只会得到1条记录。

1 个答案:

答案 0 :(得分:0)

有多种方法可以定义功能,这些功能将完全满足您的要求。

我只会显示一种可能性,这是一个非常幼稚的解决方案。您可以遍历所有列组合,并检查它们是否在表中形成唯一条目:

import itertools as it

def find_all_unique_columns_naive(df):
    cols = df.columns

    res = []
    for num_of_cols in range(1, len(cols) + 1):
        for comb in it.combinations(cols, num_of_cols):
            num_of_nonunique = df.groupBy(*comb).count().where("count > 1").count()

            if not num_of_nonunique:
                res.append(comb)
    return res

您的示例结果为:

[('Name',), ('id',), ('Name', 'Role'), ('Name', 'id'), ('Role', 'id'), 
 ('Name', 'Role', 'id')]

显然存在性能问题,因为此功能随着列数(即O(2^N))的增加而随着时间呈指数增长。意味着只有20列的表的运行时间将花费相当长的时间。

不过,有一些明显的方法可以加快速度,例如如果您已经知道列Name是唯一的,那么包括已知的唯一组合的任何组合都将保持唯一,因此,您可以凭此事实推断出组合(Name, Role), (Name, id)和{{1} }也是唯一的,这肯定会有效地减少搜索空间。但是,最坏的情况仍然保持不变,即,如果表没有唯一的列组合,则您必须耗尽整个搜索空间才能得出结论。

最后,我建议您首先考虑一下为什么要使用此功能。我同意小表可能有一些特定的用例,只是为了节省一些时间,但老实说,这不是应该如何处理表的方法。如果存在一个表,则应该有一个存在该表的目的和适当的表设计,即表中的数据是如何真正构造和更新的。这应该是寻找唯一标识符的起点。因为即使您现在可以使用此方法找到其他唯一标识符,也很可能表设计将在下次更新时销毁它们。我宁愿建议使用表的元数据和文档,因为这样可以确保按设计时的正确方式处理表,并且如果表中有很多列,则实际上速度会更快