NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #251 most downloaded on PyPI
Extremely lightweight compatibility layer between dataframe libraries
Last release 23 days ago
08 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
3 years old
243 releases · first in 2024
[pre-commit.ci] pre-commit autoupdate
n_unique (#917)by argument in join_asof (#921)on key in join_asof (#916)uv in contributing guide (#873)dt.date tests for cuDF (#912)Thank you to all our contributors for making this release possible! @AlessandroMiola, @FBruzzesi, @IsaiasGutierrezCruz, @LiamConnors, @MarcoGorelli, @luke396, @pre-commit-ci, @pre-commit-ci[bot], @raisadz and @thomasjpfan
fix: compatiblity with Python3.8 for Ibis
One column per month.
Thank you to all our contributors for making this release possible! @MarcoGorelli
patch: Improve q10, q11, q2, q3, q4, and q5 queries
write_csv docstring (#895)concat (#808)narwhals/ and tests/ (#885)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @EdAbati, @FBruzzesi, @LiamConnors, @MarcoGorelli, @Nikoleta-v3, @Sherwin-14, @luke396 and @montanarograziano
patch: Improving typing of stable from_native when 'strict=False'
from_native when 'strict=False' (#875)concat function (#869)concat method (#840)cast (#821)maybe_get_index (#867)from_native when 'strict=True' (#865)CONTRIBUTING.md (#851)utils/ from build (#879)Thank you to all our contributors for making this release possible! @EdAbati, @FBruzzesi, @MarcoGorelli, @aidoskanapyanov, @anopsy, @benrutter and @luke396
Revert "patch: allow lit to broadcast as left operand"
lit to broadcast as left operand" (#858)lit to broadcast as left operand (#854)nw.col (#855)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli and @aivanoved
feat: Add is_pandas_like_dataframe and is_pandas_like_series
sum_horizontal ignore nulls (#825)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi, @MarcoGorelli and @anopsy
feat: dask in api-completeness table
DaskExpr.quantile (#835)mean_horizontal (#843)__getitem__ with slices for columns (#839)to_numpy and to_list in tests (#842)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi, @MarcoGorelli and @anopsy
fix: __array__ for pandas (pyarrow dtypes) was raising for old versions of PyArrow
__array__ for pandas (pyarrow dtypes) was raising for old versions of PyArrow (#837)Thank you to all our contributors for making this release possible! @MarcoGorelli
feat: support dtype and copy in DataFrame.__array__
select for pandas backend (#828)Thank you to all our contributors for making this release possible! @DeaMariaLeon and @MarcoGorelli
feat: add dt.to_string to DaskExpr
dt.to_string to DaskExpr (#796)DaskExpr.total_minutes, total_seconds, total_milliseconds, total_microseconds, total_nanoseconds (#811)is_unique & is_duplicated (#803)is_in to DaskExpr and mark is_duplicated and is_unique as not implemented (#802)to_numpy (#820)to_list() (#812)duration_attribute_tests (#798)narwhalify de-duplication (#799)cudf_constructor to conftest (#797)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi, @MarcoGorelli, @benrutter, @lucianosrp, @luke396 and @thomasjpfan
[pre-commit.ci] pre-commit autoupdate
diff() method to Dask backend (#793)Expr.null_count (#792)Thank you to all our contributors for making this release possible! @MarcoGorelli, @anopsy, @pre-commit-ci, @pre-commit-ci[bot] and @raisadz
feat: Support Arrow PyCapsule Interface for export
to_pandas / to_numpy / to_arrow (#783)drop method (#773)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli and @anopsy
perf: remove some lambdas from _dask backend
from_dict to not have native_namespace arg if all inputs are already narwhals Series (#760)drop_nulls method (#779)str.replace and str.replace_all (#750)sum_horizontal (#775)lit method (#772)DaskSelectorNamespace (#771)to_arrow method (#770)to_arrow method (#769)is_first|last_distinct methods (#764)__invert__, is_null, n_unique methods (#763)len method (#762)Series.pipe and Expr.pipe (#582)Series.cat page (#755)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @lucianosrp and @muddi900
perf: keep nw.len totally lazy for dask
nw.len totally lazy for dask (#749)Expr.any and Expr.all to Dask (#748)__mod__ method (#618)Expr.abs to Dask (#728)Expr.count (#731)date to datetime namespace (#713)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @anopsy, @lucianosrp and @mistShard
Feat: Series.shift Pyarrow Backend Implementation
Series.shift Pyarrow Backend Implementation (#590)clip method (#729)Expr.std (#734)unique method (#726)join and sort, DaskNamespace all (#725)group_by to dask (#718)clip method (#701)Expr.round to Dask (#709)strip_chars to string namespace (#715)ArrowGroupBy.__iter__ method (#717)over method (#721)with_row_index and rename (#692)round to Arrow (#696)any_horizontal and generalize all_horizontal (#693)drop method (#699)schema and collect_schema (#688)Expr.max and test (#691)Expr.min and test (#690)how_it_works.md (#707)from_native (dask) (#733)test_common.py (#720)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi, @MarcoGorelli, @aidoskanapyanov, @aivanoved, @amol-, @anopsy, @condekind, @lucianosrp, @mfonekpo and @mistShard
Feat: Dask filter and __and__ method added
iter_rows inconsistency in pandas (#671)fill_null to DaskExpr (#685)drop_nulls for dask (#675)columns property & filter method (#670)select method (#667)to_lowercase, to_uppercase, to_datetime for dask (#665)ends_with, contains, slice for dask (#664)Expr.sum (#662)dt.nanosecond implementation (#678)UserWarning error while using pandas `group_by's (#677)system_info tests outside test_common (#680)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @EdAbati, @FBruzzesi, @MarcoGorelli, @aidoskanapyanov, @benrutter, @lucianosrp, @mistShard and @montanarograziano
skip changelog(deps): bump sigstore/gh-action-sigstore-python from 2.1.1 to 3.0.0
Expr.__sub__ (#643)starts_with for dask (#648)is_between for dask (#642)Expr.__mul__ and test cases (#644)test_std outside test_common (#657)test_schema and test_collect_schema out of test_common (#655)from_dict function (#626)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi, @MarcoGorelli, @aidoskanapyanov, @anopsy, @dependabot, @dependabot[bot], @montanarograziano and @ugohuche
feat: raise informative error if getitem is used in unsupported manner
gather_every methods (#619)df_any/s_any with df/s (#621)test_empty_select out of test_common (to existing select_test.py) (#617)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @aidoskanapyanov and @condekind
cleaning: remove series.is_between from backend completness
is_between and is_between_test.py (#609)schema argument to from_dict function (#606)any_horizontal function (#605)quantile method (#600)iter_rows (#596)Series.value_count spec enhancement (#583)nulls_last argument in Series/Expr.sort (#580)Implementation for all backends (#608)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @aidoskanapyanov and @anopsy
perf: fastpath for simple select in pandas-like
drop_test out of test_common (#586)concat_test out of test_common (#585)item_test out of test_common (#584)Thank you to all our contributors for making this release possible! @MarcoGorelli and @aidoskanapyanov
Add additional sponsors and institutional partners to README
Series.__getitem__ typing (#569)Series.to_dummies, arrow sort and unique (#577)Thank you to all our contributors for making this release possible! @EdAbati, @FBruzzesi, @InessaPawson, @MarcoGorelli, @anopsy and @mfonekpo
feat: Implement n_unique for pyarrow
ExprNameNamespace (#552)unique, is_duplicated, is_unique (#565)__floordiv__ and __rfloordiv__ for pyarrow (#544)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @lucianosrp and @mistShard
added arrow is_in, changed the names of test folders
sample (#550)zip_with (#548)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli and @anopsy
feat: allow nw.len in groupby for arrow
ArrowExprCatNamespace (#536)is_null and __invert__ to pyarrow series (#534)concat (#525)lit (#524)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @anopsy, @lucianosrp and @mfonekpo
feat: pyarrow item, is_empty, rename, write_parquet
_create_compliant_series (#508)item, is_empty, rename, write_parquet (#520)collect_schema method (#516)from_native raise invalid comb (#519)native_dataframe in from_native (#518)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi and @MarcoGorelli
Refactor: Re enable and fix Ruff's TRY Checks
translate module coverage (#501)all_horizontal (#502)sum_horizontal (#503)filter, comparand and logic operators (#491)Thank you to all our contributors for making this release possible! @ELC, @FBruzzesi, @MarcoGorelli, @brentomagic and @ugohuche
bug: fix __getitem__ for tuple of row and col keys
Thank you to all our contributors for making this release possible! @DeaMariaLeon, @EdAbati, @FBruzzesi, @MarcoGorelli, @condekind and @ugohuche
clean: (partial) factor test_common
test_common (#482)Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli, @lucianosrp and @mfonekpo
ci: ignore em101, make random ci more robust (maybe)
to_lowercase and to_uppercase to PandasExpr.str namespace (#455)Thank you to all our contributors for making this release possible! @ELC, @FBruzzesi, @MarcoGorelli and @lucianosrp
Nothing published for this version
feat: allow dt.microsecond and dt.millisecond in old pyarrow-backed p…
typing link (#435)Thank you to all our contributors for making this release possible! @ELC, @FBruzzesi and @MarcoGorelli
clean: factor test_ _instantiation out of test_common
test_<lazy|eager>_instantiation out of test_common (#428)typing link (#435)Thank you to all our contributors for making this release possible! @ELC, @FBruzzesi, @MarcoGorelli and @condekind
clean: factor filter_test and filter_test_series out of test_common
filter_test and filter_test_series out of test_common (#427)native in some names / functions (#424)parse_version (#430)Thank you to all our contributors for making this release possible! @EdAbati, @MarcoGorelli, @condekind, @shriyakalakata and @ugohuche
Thank you to all our contributors for making this release possible! @EdAbati and @MarcoGorelli
clone for dataframes (#406)Thank you to all our contributors for making this release possible! @EdAbati and @MarcoGorelli
add tpch q21 notebook, remove outdated scripts
dtype could not be passed to Series.array (#403)sort_test out of test_common (#400)Thank you to all our contributors for making this release possible! @FBruzzesi and @MarcoGorelli
lower minimum pandas version to 0.25.3
Why (#391)Thank you to all our contributors for making this release possible! @MarcoGorelli and @luke396
feat: add Expr.cast and Series.cast for PyArrow backend
Thank you to all our contributors for making this release possible! @FBruzzesi, @MarcoGorelli and @luke396
feat: add is_ordered_categorical
Thank you to all our contributors for making this release possible! @MarcoGorelli
feat: add unknown dtype for polars backend
constructor fixture for tests (#373)Thank you to all our contributors for making this release possible! @FBruzzesi and @MarcoGorelli
bug: don't skip arrow tests on macOS
Thank you to all our contributors for making this release possible! @EdAbati and @MarcoGorelli
Fix compatibility with older NumPy versions https://github.com/narwhals-dev/narwhals/pull/364
Add TypeGuard for is_pandas_dataframe: https://github.com/narwhals-dev/narwhals/pull/362
TypeGuard for is_pandas_dataframe: https://github.com/narwhals-dev/narwhals/pull/362refactor: always recommend from_native https://github.com/narwhals-dev/narwhals/pull/358
from_native https://github.com/narwhals-dev/narwhals/pull/358is_pandas_dataframe: https://github.com/narwhals-dev/narwhals/pull/361feat: add more methods to the pyarrow backend
from_native (#358)get_ functions from translate (#354)Thank you to all our contributors for making this release possible! @EdAbati, @MarcoGorelli, @Priyansh121096 and @skrawcz
feat: support Date dtype in Narwhals
narwhalify (#328)series_from_iterable (#335)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @EdAbati, @FBruzzesi, @MarcoGorelli and @marenwestermann
feat: add cat.get_categories, make test numpy2.0 compatible
Thank you to all our contributors for making this release possible! @MarcoGorelli
docs: Update docstrings for filter
Thank you to all our contributors for making this release possible! @DeaMariaLeon, @MarcoGorelli, @Priyansh121096 and @marenwestermann
Thank you to all our contributors for making this release possible! @FBruzzesi and @MarcoGorelli
Expr.len and Series.len (#323)Thank you to all our contributors for making this release possible! @FBruzzesi and @MarcoGorelli
web: add community calendar link
narwhals.lit (#321)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @EdAbati, @MarcoGorelli and @marenwestermann
perf: use fastpath in with_columns
Thank you to all our contributors for making this release possible! @MarcoGorelli
enh: series and expr round method
slice, starts_with, tail methods for str namespace (#305)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi and @MarcoGorelli
Expression String Method - Contains
Thank you to all our contributors for making this release possible! @DeaMariaLeon, @MarcoGorelli, @marenwestermann and @ugohuche
enh: dataframe and series .item()
.head() and .tail() (#297).item() (#296)Thank you to all our contributors for making this release possible! @DeaMariaLeon, @FBruzzesi and @MarcoGorelli
feat: strftime for datetime namespace
strftime for datetime namespace (#291)Thank you to all our contributors for making this release possible! @FBruzzesi and @MarcoGorelli
Nothing published for this version
perf: use copy=False in set_axis where possible
Thank you to all our contributors for making this release possible!
docs: update contributing guide
Thank you to all our contributors for making this release possible! @DeaMariaLeon, @MarcoGorelli, @brentomagic and @mfonekpo
Fixed casting to String for non-nullables dtypes in pandas (https://github.com/narwhals-dev/narwhals/pull/254). Thanks @GRcharles for reporting the is
dtype backend is preserved by pandas in casts https://github.com/narwhals-dev/narwhals/pull/248
Selectors now support set operations: https://github.com/narwhals-dev/narwhals/pull/247
Hopefully we'll figure out how to use https://github.com/marketplace/actions/release-drafter for the next one
Your coding agent can read these notes before it upgrades. Set up the MCP server →