{"id":14428156,"url":"https://github.com/narwhals-dev/narwhals","last_synced_at":"2026-01-06T10:14:11.361Z","repository":{"id":223341661,"uuid":"760058710","full_name":"narwhals-dev/narwhals","owner":"narwhals-dev","description":"Lightweight and extensible compatibility layer between dataframe libraries!","archived":false,"fork":false,"pushed_at":"2025-08-20T22:23:58.000Z","size":12406,"stargazers_count":1245,"open_issues_count":181,"forks_count":162,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-08-20T23:39:42.904Z","etag":null,"topics":["cudf","dask","duckdb","ibis","pandas","polars","pyarrow","pyspark"],"latest_commit_sha":null,"homepage":"https://narwhals-dev.github.io/narwhals/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/narwhals-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-02-19T17:51:14.000Z","updated_at":"2025-08-20T21:57:37.000Z","dependencies_parsed_at":"2024-02-27T11:34:31.606Z","dependency_job_id":"d522c663-5b0b-4e47-bb7d-5325c090d3f5","html_url":"https://github.com/narwhals-dev/narwhals","commit_stats":null,"previous_names":["marcogorelli/puffin","marcogorelli/narwhals","narwhals-dev/narwhals"],"tags_count":245,"template":false,"template_full_name":null,"purl":"pkg:github/narwhals-dev/narwhals","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narwhals-dev%2Fnarwhals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narwhals-dev%2Fnarwhals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narwhals-dev%2Fnarwhals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narwhals-dev%2Fnarwhals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/narwhals-dev","download_url":"https://codeload.github.com/narwhals-dev/narwhals/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narwhals-dev%2Fnarwhals/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272143676,"owners_count":24881136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cudf","dask","duckdb","ibis","pandas","polars","pyarrow","pyspark"],"created_at":"2024-08-30T12:01:18.152Z","updated_at":"2026-01-06T10:14:11.349Z","avatar_url":"https://github.com/narwhals-dev.png","language":"Python","readme":"# Narwhals\n\n\u003ch1 align=\"center\"\u003e\n\t\u003cimg\n\t\twidth=\"400\"\n\t\talt=\"narwhals_small\"\n\t\tsrc=\"https://github.com/user-attachments/assets/968545af-ea0f-48bb-8377-144e93f7abf8\"\u003e\n\u003c/h1\u003e\n\n[![PyPI version](https://badge.fury.io/py/narwhals.svg)](https://badge.fury.io/py/narwhals)\n[![Downloads](https://static.pepy.tech/badge/narwhals/month)](https://pepy.tech/project/narwhals)\n[![Trusted publishing](https://img.shields.io/badge/Trusted_publishing-Provides_attestations-bright_green)](https://peps.python.org/pep-0740/)\n[![PYPI - Types](https://img.shields.io/pypi/types/narwhals)](https://pypi.org/project/narwhals)\n\nExtremely lightweight and extensible compatibility layer between dataframe libraries!\n\n- **Full API support**: cuDF, Modin, pandas, Polars, PyArrow.\n- **Lazy-only support**: Daft, Dask, DuckDB, Ibis, PySpark, SQLFrame.\n\nSeamlessly support all, without depending on any!\n\n- ✅ **Just use** [a subset of **the Polars API**](https://narwhals-dev.github.io/narwhals/api-reference/), no need to learn anything new\n- ✅ **Zero dependencies**, Narwhals only uses what\n  the user passes in so your library can stay lightweight\n- ✅ Separate **lazy** and eager APIs, use **expressions**\n- ✅ Support pandas' complicated type system and index, without\n  either getting in the way\n- ✅ **100% branch coverage**, tested against pandas and Polars nightly builds\n- ✅ **Negligible overhead**, see [overhead](https://narwhals-dev.github.io/narwhals/overhead/)\n- ✅ Let your IDE help you thanks to **full static typing**, see [typing](https://narwhals-dev.github.io/narwhals/api-reference/typing/)\n- ✅ **Perfect backwards compatibility policy**,\n  see [stable api](https://narwhals-dev.github.io/narwhals/backcompat/) for how to opt-in\n\nGet started!\n\n- [Read the documentation](https://narwhals-dev.github.io/narwhals/)\n- [Chat with us on Discord!](https://discord.gg/V3PqtB4VA4)\n- [Join our community call](https://calendar.google.com/calendar/embed?src=27ff6dc5f598c1d94c1f6e627a1aaae680e2fac88f848bda1f2c7946ae74d5ab%40group.calendar.google.com)\n- [Read the contributing guide](https://github.com/narwhals-dev/narwhals/blob/main/CONTRIBUTING.md)\n\n\u003cdetails\u003e\n\u003csummary\u003eTable of contents\u003c/summary\u003e\n\n- [Narwhals](#narwhals)\n  - [Installation](#installation)\n  - [Usage](#usage)\n  - [Example](#example)\n  - [Scope](#scope)\n  - [Roadmap](#roadmap)\n  - [Used by](#used-by)\n  - [Sponsors and institutional partners](#sponsors-and-institutional-partners)\n  - [Support](#support)\n  - [Appears on](#appears-on)\n  - [Why \"Narwhals\"?](#why-narwhals)\n\n\u003c/details\u003e\n\n## Installation\n\n- pip (recommended, as it's the most up-to-date)\n  ```\n  pip install narwhals\n  ```\n- conda-forge (also fine, but the latest version may take longer to appear)\n  ```\n  conda install -c conda-forge narwhals\n  ```\n\n## Usage\n\nThere are three steps to writing dataframe-agnostic code using Narwhals:\n\n1. use `narwhals.from_native` to wrap a pandas/Polars/Modin/cuDF/PyArrow\n   DataFrame/LazyFrame in a Narwhals class\n2. use the [subset of the Polars API supported by Narwhals](https://narwhals-dev.github.io/narwhals/api-reference/)\n3. use `narwhals.to_native` to return an object to the user in its original\n   dataframe flavour. For example:\n\n   - if you started with pandas, you'll get pandas back\n   - if you started with Polars, you'll get Polars back\n   - if you started with Modin, you'll get Modin back (and compute will be distributed)\n   - if you started with cuDF, you'll get cuDF back (and compute will happen on GPU)\n   - if you started with PyArrow, you'll get PyArrow back\n\n\u003ch1 align=\"left\"\u003e\n\t\u003cimg\n\t\twidth=\"600\"\n\t\talt=\"narwhals_gif\"\n\t\tsrc=\"https://github.com/user-attachments/assets/88292d3c-6359-4155-973d-d0f8e3fbf5ac\"\u003e\n\n\u003c/h1\u003e\n\n## Example\n\nNarwhals allows you to define dataframe-agnostic functions. For example:\n\n```python\nimport narwhals as nw\nfrom narwhals.typing import IntoFrameT\n\n\ndef agnostic_function(\n    df_native: IntoFrameT,\n    date_column: str,\n    price_column: str,\n) -\u003e IntoFrameT:\n    return (\n        nw.from_native(df_native)\n        .group_by(nw.col(date_column).dt.truncate(\"1mo\"))\n        .agg(nw.col(price_column).mean())\n        .sort(date_column)\n        .to_native()\n    )\n```\n\nYou can then pass `pandas.DataFrame`, `polars.DataFrame`, `polars.LazyFrame`, `duckdb.DuckDBPyRelation`,\n`pyspark.sql.DataFrame`, `pyarrow.Table`, and more, to `agnostic_function`. In each case, no additional\ndependencies will be required, and computation will stay native to the input library:\n\n```python\nimport pandas as pd\nimport polars as pl\nfrom datetime import datetime\n\ndata = {\n    \"date\": [datetime(2020, 1, 1), datetime(2020, 1, 8), datetime(2020, 2, 3)],\n    \"price\": [1, 4, 3],\n}\nprint(\"pandas result:\")\nprint(agnostic_function(pd.DataFrame(data), \"date\", \"price\"))\nprint()\nprint(\"Polars result:\")\nprint(agnostic_function(pl.DataFrame(data), \"date\", \"price\"))\n```\n\n```terminal\npandas result:\n        date  price\n0 2020-01-01    2.5\n1 2020-02-01    3.0\n\nPolars result:\nshape: (2, 2)\n┌─────────────────────┬───────┐\n│ date                ┆ price │\n│ ---                 ┆ ---   │\n│ datetime[μs]        ┆ f64   │\n╞═════════════════════╪═══════╡\n│ 2020-01-01 00:00:00 ┆ 2.5   │\n│ 2020-02-01 00:00:00 ┆ 3.0   │\n└─────────────────────┴───────┘\n```\n\nSee the [tutorial](https://narwhals-dev.github.io/narwhals/basics/dataframe/) for several examples!\n\n## Scope\n\n- Do you maintain a dataframe-consuming library?\n- Do you have a specific Polars function in mind that you would like Narwhals to have in order to make your work easier?\n\nIf you said yes to both, we'd love to hear from you!\n\n## Roadmap\n\nSee [roadmap discussion on GitHub](https://github.com/narwhals-dev/narwhals/discussions/1370)\nfor an up-to-date plan of future work.\n\n## Used by\n\nJoin the party!\n\n- [altair](https://github.com/vega/altair/)\n- [bokeh](https://github.com/bokeh/bokeh)\n- [darts](https://github.com/unit8co/darts)\n- [fairlearn](https://github.com/fairlearn/fairlearn)\n- [formulaic](https://github.com/matthewwardrop/formulaic)\n- [gt-extras](https://github.com/posit-dev/gt-extras)\n- [hierarchicalforecast](https://github.com/Nixtla/hierarchicalforecast)\n- [marimo](https://github.com/marimo-team/marimo)\n- [metalearners](https://github.com/Quantco/metalearners)\n- [mosaic](https://github.com/uwdata/mosaic)\n- [panel-graphic-walker](https://github.com/panel-extensions/panel-graphic-walker)\n- [plotly](https://plotly.com)\n- [pointblank](https://github.com/posit-dev/pointblank)\n- [pymarginaleffects](https://github.com/vincentarelbundock/pymarginaleffects)\n- [pyreadstat](https://github.com/Roche/pyreadstat)\n- [py-shiny](https://github.com/posit-dev/py-shiny)\n- [rio](https://github.com/rio-labs/rio)\n- [scikit-lego](https://github.com/koaning/scikit-lego)\n- [scikit-playtime](https://github.com/koaning/scikit-playtime)\n- [tabmat](https://github.com/Quantco/tabmat)\n- [tea-tasting](https://github.com/e10v/tea-tasting)\n- [timebasedcv](https://github.com/FBruzzesi/timebasedcv)\n- [tubular](https://github.com/lvgig/tubular)\n- [Validoopsie](https://github.com/akmalsoliev/Validoopsie)\n- [vegafusion](https://github.com/vega/vegafusion)\n- [wimsey](https://github.com/benrutter/wimsey)\n\nFeel free to add your project to the list if it's missing, and/or\n[chat with us on Discord](https://discord.gg/V3PqtB4VA4) if you'd like any support.\n\n## Sponsors and institutional partners\n\nNarwhals is 100% independent, community-driven, and community-owned.\nWe are extremely grateful to the following organisations for having\nprovided some funding / development time:\n\n- [Quansight Labs](https://labs.quansight.org)\n- [Quansight Futures](https://www.qi.ventures)\n- [OpenTeams](https://www.openteams.com)\n- [POSSEE initiative](https://possee.org)\n- [BYU-Idaho](https://www.byui.edu)\n\nIf you contribute to Narwhals on your organization's time, please let us know. We'd be happy to add your employer\nto this list!\n\n## Support\n\nIf you'd like to say \"thank you\", please give us a ⭐ star ⭐.\n\nPlease contact [hello_narwhals@proton.me](hello_narwhals@proton.me) if you would like to:\n\n- Receive professional support (e.g., if you're using or would like to use Narwhals at your company).\n- Have any Narwhals fixes / features prioritised.\n- Commission any Narwhals plugins for new backends.\n\n## Appears on\n\nNarwhals has been featured in several talks, podcasts, and blog posts:\n\n- [Inspiring Computing Podcast](https://www.inspiringcomputing.com/2107763/episodes/16702460-the-rise-of-narwhals-in-open-source)\n  The Rise of Narwhals in Open-Source\n\n- [PyCon DE \u0026 PyData 2025](https://youtu.be/DJk782DWcss)\n  How Narwhals is silently bringing pandas, Polars, DuckDB, PyArrow, and more together\n\n- [The Python Exchange March 2025](https://youtu.be/TvFWFlK-2po)\n  What Can Narwhals Do for You?\n\n- [PyData London 2025](https://youtu.be/r2PxJlO7_QA)\n  How Narwhals brings Polars, DuckDB, PyArrow, \u0026 pandas together\n\n- [Talk Python to me Podcast](https://youtu.be/FSH7BZ0tuE0)\n  Ahoy, Narwhals are bridging the data science APIs\n\n- [Python Bytes Podcast](https://www.youtube.com/live/N7w_ESVW40I?si=y-wN1uCsAuJOKlOT\u0026t=382)\n  Episode 402, topic #2\n\n- [Super Data Science: ML \u0026 AI Podcast](https://www.youtube.com/watch?v=TeG4U8R0U8U)  \n  Narwhals: For Pandas-to-Polars DataFrame Compatibility\n\n- [Sample Space Podcast | probabl](https://youtu.be/8hYdq4sWbbQ?si=WG0QP1CZ6gkFf18b)  \n  How Narwhals has many end users ... that never use it directly. - Marco Gorelli\n\n- [The Real Python Podcast](https://www.youtube.com/watch?v=w5DFZbFYzCM)\n  Narwhals: Expanding DataFrame Compatibility Between Libraries\n\n- [Pycon Lithuania 2024](https://www.youtube.com/watch?v=-mdx7Cn6_6E)  \n  Marco Gorelli - DataFrame interoperatiblity - what's been achieved, and what comes next?\n\n- [Pycon Italy 2024](https://www.youtube.com/watch?v=3IqUli9XsmQ)  \n  How you can write a dataframe-agnostic library - Marco Gorelli\n\n- [Polars Blog Post](https://pola.rs/posts/lightweight_plotting/)  \n  Polars has a new lightweight plotting backend\n\n- [Quansight Labs blog post (w/ Scikit-Lego)](https://labs.quansight.org/blog/scikit-lego-narwhals)  \n  How Narwhals and scikit-lego came together to achieve dataframe-agnosticism\n\n## Why \"Narwhals\"?\n\n[Coz they are so awesome](https://youtu.be/ykwqXuMPsoc?si=A-i8LdR38teYsos4).\n\nThanks to [Olha Urdeichuk](https://www.fiverr.com/olhaurdeichuk) for the illustration!\n","funding_links":[],"categories":["Data Manipulation","Libraries/Packages/Scripts","Python","Libraries","Libraries Powered by DuckDB"],"sub_categories":["Polars plugins"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarwhals-dev%2Fnarwhals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnarwhals-dev%2Fnarwhals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarwhals-dev%2Fnarwhals/lists"}