#28903·polars

DataFrame `n_unique()` ignores additional columns when the `subset` parameter is an expression or selector that selects multiple columns

Author: nastasie-octavianCreated Aug 20, 2026Updated Sep 17, 2026
LabelsbugpythonacceptedP-highA-selectors

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

python
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

bash

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.

python
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 3

However, if the sequence has more than one element, the multi-column expressions/selectors in the sequence work fine, e.g.

python
assert df.n_unique(subset=["A", pl.col("B", "id")]) == 6  # Passes

The DataFrame unique() method doesn't have these issues.

python
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  # Passes

Expected 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>