我的目的是编写一个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条记录。
答案 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} }也是唯一的,这肯定会有效地减少搜索空间。但是,最坏的情况仍然保持不变,即,如果表没有唯一的列组合,则您必须耗尽整个搜索空间才能得出结论。
最后,我建议您首先考虑一下为什么要使用此功能。我同意小表可能有一些特定的用例,只是为了节省一些时间,但老实说,这不是应该如何处理表的方法。如果存在一个表,则应该有一个存在该表的目的和适当的表设计,即表中的数据是如何真正构造和更新的。这应该是寻找唯一标识符的起点。因为即使您现在可以使用此方法找到其他唯一标识符,也很可能表设计将在下次更新时销毁它们。我宁愿建议使用表的元数据和文档,因为这样可以确保按设计时的正确方式处理表,并且如果表中有很多列,则实际上速度会更快