Registry / data / narwhals

narwhals

JSON →
library2.18.1pypypi✓ verified 52d ago

Narwhals is an extremely lightweight and extensible compatibility layer between dataframe libraries. It provides a unified API, largely mirroring the Polars API, enabling users to write dataframe-agnostic code that works across various backends such as pandas, Polars, cuDF, PyArrow, Dask, DuckDB, Ibis, PySpark, and SQLFrame. It is currently at version 2.18.1 and maintains an active development cycle with frequent releases, often including weekly or bi-weekly updates for bug fixes and minor enhancements.

datadatabaseserialization
pip install narwhals
Install & Compatibility
Where this runs
tested against v2.22.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.925 runs
installs and imports cleanly · install 0.0s · import 0.152s · 22.3MB
glibc
py 3.103.925 runs
installs and imports cleanly · install 1.9s · import 0.154s · 23MB
21MB installed
● package 21MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

narwhals
import narwhals as nw
IntoFrameT
from narwhals.typing import IntoFrameT
Useful for type hinting dataframe-agnostic functions
stable.v1
import narwhals.stable.v1 as nw_stable
Use this for long-term API stability in library development, though the main 'narwhals' namespace is more actively developed for new features.

This quickstart demonstrates how to write a dataframe-agnostic function using Narwhals. The function `process_data` accepts any supported native dataframe type (e.g., pandas DataFrame, Polars DataFrame) via `nw.from_native`, applies a group-by and aggregation operation using Narwhals' Polars-like API, and then converts the result back to the original native dataframe type using `to_native()`.

import narwhals as nw import pandas as pd import polars as pl from narwhals.typing import IntoFrameT def process_data(df_native: IntoFrameT) -> IntoFrameT: df = nw.from_native(df_native) result = ( df.group_by(nw.col('category')) .agg(nw.col('value').mean().alias('mean_value')) .sort('mean_value', descending=True) ) return result.to_native() # Example with pandas pd_df = pd.DataFrame({'category': ['A', 'B', 'A', 'C'], 'value': [10, 20, 15, 25]}) pd_result = process_data(pd_df) print('Pandas Result:') print(pd_result) # Example with polars pl_df = pl.DataFrame({'category': ['A', 'B', 'A', 'C'], 'value': [10, 20, 15, 25]}) pl_result = process_data(pl_df) print('\nPolars Result:') print(pl_result)
Debug
Known issues
gotchaNarwhals is a compatibility layer and does not provide dataframe functionality itself. You must install the underlying dataframe libraries (e.g., `pandas`, `polars`, `pyarrow`) separately for Narwhals to function with those backends. Not installing them will lead to `ModuleNotFoundError` or `TypeError` when `from_native` is used.
fix
Install the desired backend libraries, e.g., `pip install pandas polars pyarrow`.
affects: All versions
breakingThe main `narwhals` namespace may undergo breaking changes, deprecations, or API shifts in new releases. For critical library development requiring long-term stability, prefer `import narwhals.stable.v1 as nw_stable`. This stable API is promised to never change or remove public functions. Future stable versions (e.g., `v2`, `v3`) will be introduced if breaking changes are necessary.
fix
For production code or libraries, use `import narwhals.stable.v1 as nw` and adhere to its API. For experimentation, the main `narwhals` namespace is acceptable.
affects: All versions, for code not using `narwhals.stable.v1`
gotchaNarwhals implements a *subset* of the Polars API. Not all Polars functions, arguments, or behaviors are necessarily supported or identically replicated across all backends. Complex or less common Polars operations might not be available or might behave differently in specific backend implementations. Always consult the official Narwhals API completeness documentation.
fix
Refer to the Narwhals documentation for supported API elements. If a specific Polars feature is critical and not supported, you may need to handle that backend natively or contribute to Narwhals.
affects: All versions
gotchaNarwhals preserves the eager/lazy execution model of the underlying dataframe. If you pass a lazy frame (e.g., Polars LazyFrame, Dask DataFrame), operations remain lazy. Explicitly call `.collect()` when an eager result is required, especially before operations like `.shape` or `.pivot()`, which necessitate materializing the data. Failing to do so can lead to errors or unexpected behavior.
fix
Identify points in your code where eager computation is implicitly or explicitly needed and call `.collect()` on your Narwhals LazyFrame. Alternatively, use `eager_only=True` in `nw.from_native` if you always expect an eager frame.
affects: All versions
deprecatedExternal library deprecations can affect Narwhals. For example, DuckDB 1.5 deprecated `fetch_arrow_table`. While Narwhals strives to adapt, relying on specific backend versions might expose you to these upstream changes. This is particularly relevant for `when/then` conditions, `join` operations, and null value handling across different backends, which have seen several fixes in recent versions.
fix
Keep Narwhals updated to benefit from fixes addressing upstream deprecations and inconsistencies. Thoroughly test your code across different backend versions and with various null value scenarios.
affects: V2.10.2 onwards (intermittent fixes)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'narwhals'
The `narwhals` library is not installed in your Python environment.
fix
Install the library using pip: `pip install narwhals`
narwhals.exceptions.ColumnNotFoundError: Column 'column_name' not found.
An operation was attempted on a column name that does not exist in the DataFrame or LazyFrame.
fix
Verify the column name for typos or confirm its existence using `df.columns` or `df.collect().columns` (for LazyFrames) to inspect available columns.
TypeError: Expected an object which can be converted into an expression, got <class 'int'>
Narwhals' expression-based API requires explicit wrapping of literal values (e.g., integers, strings) with `nw.lit()` or column selections by index with `nw.col()` in operations like `select` or `with_columns`.
fix
Wrap literal values with `nw.lit()` (e.g., `nw.lit(0)` instead of `0`) and select columns by index or non-string names with `nw.col()` (e.g., `nw.col(0)` instead of `0`).
AttributeError: 'DataFrame' object has no attribute 'some_polars_method'
Narwhals implements a subset of the Polars API. The specific method or attribute being called exists in the native Polars library but is not currently exposed or supported by the Narwhals compatibility layer.
fix
Refer to the Narwhals documentation for supported API features. If the functionality is critical and unavailable, convert to the native backend using `.to_native()` to perform the operation, and then wrap the result back with `nw.from_native()` if further Narwhals operations are needed.
Upgrade
Version history
2.22.1latest on PyPI
Audit
Dependencies
pandasoptionalCommon backend for Narwhals compatibility
polarsoptionalPrimary API inspiration and common backend for Narwhals compatibility
pyarrowoptionalCommon backend for Narwhals compatibility
Agent activity
23 hits · last 30 days
node
10
seranking-bot
4
ahrefsbot
3
Meta
1
Amazon
1
Resources