如何使用DuckDB关系型API实现n_unique(去重计数)聚合操作?
如何使用DuckDB关系型API实现n_unique(去重计数)聚合操作?
嘿,我刚好碰到过类似的情况!你已经把DuckDB的Relational API玩得有模有样了——按a分组求b的均值那部分写得完全正确,现在想实现去重计数(n_unique)却卡壳了,对吧?
问题根源
你之前尝试用duckdb.FunctionExpression('count_distinct', ...)是因为误解了函数名——DuckDB里并没有单独的count_distinct函数,正确的去重计数是基于内置的count函数,加上去重标记来实现的。
两种适配你习惯的解决方案
先回顾你创建的基础关系数据:
import duckdb rel = duckdb.sql('select * from values (1, 4), (1, 5), (2, 6) df(a, b)')
方法1:用SQL风格的聚合字符串(最简洁省心)
Relational API支持直接传入SQL风格的聚合表达式字符串,和你写原生SQL的逻辑完全一致:
result = rel.aggregate( ['count(DISTINCT b) AS n_unique_b'], # 直接写去重计数逻辑,还能给列改名 group_expr='a' ) print(result)
输出结果(格式正常,无乱码):
┌───────┬────────────┐ │ a │ n_unique_b │ │ int32 │ int64 │ ├───────┼────────────┤ │ 1 │ 2 │ │ 2 │ 1 │ └───────┴────────────┘
方法2:用FunctionExpression的正确写法(匹配你之前的编码习惯)
如果你更倾向于用API的表达式对象写法,只需要给FunctionExpression加上distinct=True参数即可:
result = rel.aggregate( [ duckdb.FunctionExpression( 'count', duckdb.ColumnExpression('b'), distinct=True # 关键:开启去重计数的核心参数 ).alias('n_unique_b') # 可选:给结果列起直观的名字 ], group_expr='a' ) print(result)
这个写法的输出和方法1完全一致。
额外备选:直接用SQL查询
如果你觉得写原生SQL更顺手,也可以用rel.sql()直接执行分组去重计数:
result = rel.sql('SELECT a, count(DISTINCT b) AS n_unique_b FROM df GROUP BY a')
备注:内容来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

