如何在Polars中去除list[str]类型列的重复行?
如何在Polars中对包含list[str]类型列的DataFrame去重
问题场景
当用Polars处理包含list[str]类型列的DataFrame时,直接调用unique(subset="values")会报错——Polars目前仅支持对内部为数值类型的列表做分组/去重操作。以下是具体场景:
示例代码
import polars as pl # 创建带有list[str]列的DataFrame data = pl.DataFrame({ "id": [1, 2, 3, 4], "values": [ ["a", "a", "a"], # 前两行的values重复 ["a", "a", "a"], ["b", "b", "b"], ["c", "d", "e"] ] }) print(data)
原输出
shape: (4, 2) ┌─────┬─────────────────┐ │ id ┆ values │ │ --- ┆ --- │ │ i64 ┆ list[str] │ ╞═════╪═════════════════╡ │ 1 ┆ ["a", "a", "a"] │ │ 2 ┆ ["a", "a", "a"] │ │ 3 ┆ ["b", "b", "b"] │ │ 4 ┆ ["c", "d", "e"] │ └─────┴─────────────────┘
报错信息
执行data.unique(subset="values")会抛出:
ComputeError: grouping on list type is only allowed if the inner type is numeric
期望结果
保留每个唯一values列表对应的第一行:
shape: (3, 2) ┌─────┬─────────────────┐ │ id ┆ values │ │ --- ┆ --- │ │ i64 ┆ list[str] │ ╞═════╪═════════════════╡ │ 1 ┆ ["a", "a", "a"] │ │ 3 ┆ ["b", "b", "b"] │ │ 4 ┆ ["c", "d", "e"] │ └─────┴─────────────────┘
解决方法
方法1:将列表转为字符串后去重
把list[str]通过分隔符拼接成字符串,基于字符串列去重后删除临时列:
result = data.with_columns( # 用|作为分隔符拼接列表元素,避免元素本身包含的字符冲突 pl.col("values").list.join("|").alias("values_str") ).unique(subset="values_str").drop("values_str") print(result)
方法2:利用哈希值标识唯一列表
将列表转为可哈希的元组,再生成哈希值,基于哈希列去重:
result = data.with_columns( # 把列表转成元组后计算哈希值 pl.col("values").map_elements(lambda x: tuple(x), return_dtype=pl.Utf8).hash().alias("values_hash") ).unique(subset="values_hash").drop("values_hash") print(result)
方法3:用窗口函数保留每组首行
通过窗口函数按列表内容分组,取每组的第一个行索引,过滤出对应行:
result = data.with_row_index().with_columns( # 按列表转成的元组分组,取每组最小的行索引 pl.col("index").min().over(pl.col("values").map_elements(tuple)).alias("min_index") ).filter(pl.col("index") == pl.col("min_index")).drop("index", "min_index") print(result)
内容的提问来源于stack exchange,提问作者Maturin
相关产品推荐
相关产品推荐

