{"record":{"id":"ab30d01b9ae3cc4c","repo":"pola-rs/polars","slug":"expected-df-width-values-when-selecting-columns","errorCode":null,"errorMessage":"expected {df.width} values when selecting columns by boolean mask, got {len(key)}","messagePattern":"expected (.+?) values when selecting columns by boolean mask, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/_utils/getitem.py","lineNumber":277,"sourceCode":"    )\n    raise TypeError(msg)\n\n\ndef _select_columns_by_index(df: DataFrame, key: Iterable[int]) -> DataFrame:\n    series = [df.to_series(i) for i in key]\n    return df.__class__(series)\n\n\ndef _select_columns_by_name(df: DataFrame, key: Iterable[str]) -> DataFrame:\n    return df._from_pydf(df._df.select(list(key)))\n\n\ndef _select_columns_by_mask(\n    df: DataFrame, key: Sequence[bool] | Series | np.ndarray[Any, Any]\n) -> DataFrame:\n    if len(key) != df.width:\n        msg = f\"expected {df.width} values when selecting columns by boolean mask, got {len(key)}\"\n        raise ValueError(msg)\n\n    indices = (i for i, val in enumerate(key) if val)\n    return _select_columns_by_index(df, indices)\n\n\n@overload\ndef _select_rows(df: DataFrame, key: SingleIndexSelector) -> Series: ...\n\n\n@overload\ndef _select_rows(df: DataFrame, key: MultiIndexSelector) -> DataFrame: ...\n\n\ndef _select_rows(\n    df: DataFrame, key: SingleIndexSelector | MultiIndexSelector\n) -> DataFrame | Series:\n    \"\"\"Select one or more rows from the DataFrame.\"\"\"\n    if isinstance(key, int):","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/_utils/getitem.py#L259-L295","documentation":"df[:, boolean_mask] selects columns by mask via _select_columns_by_mask (getitem.py:277). The mask must contain exactly one boolean per column (df.width); a mismatch raises this ValueError before anything is selected. In practice the mask is usually sized to df.height because it was computed from row data instead of the column list.","triggerScenarios":"df[:, [True, False, True]] on a frame with 2 or 4 columns; df[:, bool_np_array] where len(array) == df.height; df[:, df['flag'].to_list()] (mask built from a row column); schema changed (columns added/removed) after the mask was computed.","commonSituations":"Row/column slot confusion in tuple indexing (row filter placed in the column slot); masks generated from an earlier schema version of the frame; copying df[df['flag'].values] pandas idiom into the second slot.","solutions":["For row filtering use df.filter(pl.col('flag')) instead of putting the mask in the column slot","Build a true column mask from df.columns: keep = [c.startswith('n_') for c in df.columns]; df[:, keep]","Or select names directly: df.select([c for c, k in zip(df.columns, mask) if k])"],"exampleFix":"# before\ndf[:, df[\"flag\"].to_list()]  # len == df.height, not df.width\n\n# after\ndf.filter(pl.col(\"flag\"))","handlingStrategy":"validation","validationCode":"mask = [c.startswith(\"n_\") for c in df.columns]  # build from columns, not rows\nassert len(mask) == df.width, f\"mask len {len(mask)} != width {df.width}\"","typeGuard":"def is_column_mask_valid(df, mask) -> bool:\n    return len(mask) == df.width and all(isinstance(v, (bool, np.bool_)) for v in mask)","tryCatchPattern":null,"preventionTips":["Build column masks from df.columns, never from row data","For row filtering always use df.filter, keeping masks out of the column slot","Recompute masks after schema changes (add/drop columns)"],"tags":["python","polars","dataframe","boolean-mask","column-selection"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}