DataFrame `n_unique()` ignores additional columns when the `subset` parameter is an expression or selector that selects multiple columns
Checks
- I have checked that this issue has not already been reported.
- I have confirmed this bug exists on the latest version of Polars.
Reproducible example
df = pl.DataFrame({
"id": [1, 2, 3, 4, 5, 6],
"A": [1, 2, 3, 4, 1, 2],
"B": [1, 2, 3, 1, 1, 1,],
})
assert df.n_unique(subset=pl.col("A", "B")) == 5 # Fails, returns 4
assert df.n_unique(subset=cs.by_name("B", "A")) == 5 # Fails, returns 3
assert df.n_unique(subset=pl.exclude("id")) == 5 # Fails, returns 4"id" -> 6 unique values "A" -> 4 unique values "B" -> 3 unique values "A" & "B" together -> 5 unique rows
Columns "A" and "B" taken together have 5 unique rows. If the subset parameter of n_unique() is set to an expression or selector that selects both columns it should return 5. That doesn't happen.
Log output
Issue description
If subset is set to an expression/selector that selects multiple columns, n_unique() considers only the first column and returns the number of unique values in the first column only, the additional columns selected by the expression/selector passed to subset are ignored.
This issue also occurs when subset is set to a sequence that contains only one multi-column expression/selector.
assert df.n_unique(subset=[cs.by_name("A", "B")]) == 5 # Fails, returns 4
assert df.n_unique(subset=[pl.col("B", "id")]) == 6 # Fails, returns 3However, if the sequence has more than one element, the multi-column expressions/selectors in the sequence work fine, e.g.
assert df.n_unique(subset=["A", pl.col("B", "id")]) == 6 # PassesThe DataFrame unique() method doesn't have these issues.
assert len(df.unique(subset=pl.col("A", "B"))) == 5 # Passes
assert len(df.unique(subset=cs.by_name("B", "A"))) == 5 # Passes
assert len(df.unique(subset=pl.exclude("id"))) == 5 # Passes
assert len(df.unique(subset=[pl.col("A", "B")])) == 5 # PassesExpected behavior
If subset is set to an expression/selector that selects multiple columns, .e.g. pl.exclude("some column"), n_unique() should use all the selected columns jointly when determining the number of unique rows in the subset. Similarly, n_unique() should properly handle the case when subset is set to a sequence that consists of a single multi-column expression/selector.
Installed versions
--------Version info---------
Polars: 1.43.2
Index type: UInt32
Platform: Linux-7.1.8-arch1-3-x86_64-with-glibc2.44
Python: 3.14.7 (main, Aug 10 2026, 07:46:56) [GCC 16.1.1 20260728]
Runtime: rt32
----Optional dependencies----
Azure CLI <not installed>
adbc_driver_manager <not installed>
altair <not installed>
azure.identity <not installed>
boto3 <not installed>
cloudpickle <not installed>
connectorx <not installed>
deltalake <not installed>
fastexcel <not installed>
fsspec <not installed>
gevent <not installed>
google.auth <not installed>
great_tables <not installed>
matplotlib <not installed>
numpy <not installed>
openpyxl <not installed>
pandas <not installed>
polars_cloud <not installed>
pyarrow <not installed>
pydantic <not installed>
pyiceberg <not installed>
sqlalchemy <not installed>
torch <not installed>
xlsx2csv <not installed>
xlsxwriter <not installed>Source: pola-rs/polars