polars-map
Polars plugin providing a Map extension type stored as List(Struct({key, value})).
Deprecated — Polars 2.0 ships a native
pl.Mapand reserves the.mapnamespace, so this package is pinned topolars<2and emits aDeprecationWarningon import. Its semantics match the native type; see Migrating to nativepl.Map.
The type-preserving methods (filter, filter_keys, filter_values, merge,
intersection, difference) require a Map input so they can keep its dtype instead of
inferring it; the accessors also accept the raw List(Struct).
Installation
pip install polars-map
Supported operations (.map.*)
| Category | Methods |
|---|---|
| Accessors | entries, keys, values, len, get, contains_key |
| Filtering | filter, filter_keys, filter_values |
| Transform | eval, eval_keys, eval_values |
| Set ops | merge, intersection, difference |
| Conversion | from_entries |
| Iteration | __iter__, to_list (Series only) |
Arrow conversion
| Function | Description |
|---|---|
from_arrow(table) |
Arrow Table/RecordBatch to Polars DataFrame, preserving map<> as Map |
from_arrow_array(array) |
Arrow Array to Polars Series, preserving map<> as Map |
to_arrow(frame) |
Polars DataFrame to Arrow Table, converting Map back to map<> |
to_arrow_array(series) |
Polars Series to Arrow Array, converting Map back to map<> |
scan_arrow(source) |
Lazy scan from an Arrow source with Map preservation |
Usage
import polars as pl
import pyarrow as pa
from polars_map import Map, from_arrow, to_arrow, scan_arrow
ser = pl.Series(
"m",
[
[{"key": "a", "value": 1}, {"key": "b", "value": 2}],
[{"key": "x", "value": 10}],
],
dtype=Map(pl.String(), pl.Int64()),
)
df = pl.DataFrame([ser])
# accessors
df.select(pl.col("m").map.keys()) # [["a", "b"], ["x"]]
df.select(pl.col("m").map.values()) # [[1, 2], [10]]
df.select(pl.col("m").map.len()) # [2, 1]
# lookup
df.select(pl.col("m").map.get("a")) # [1, None]
df.select(pl.col("m").map.contains_key("a")) # [True, False]
# filtering
df.select(pl.col("m").map.filter(pl.element().struct["value"] > 1))
df.select(pl.col("m").map.filter_keys(pl.element() > "a"))
df.select(pl.col("m").map.filter_values(pl.element() >= 2))
# transform keys or values
df.select(pl.col("m").map.eval_keys(pl.element().str.to_uppercase()))
df.select(pl.col("m").map.eval_values(pl.element() * 2))
# merge: right value, left position
left = pl.Series(
"l",
[[{"key": "a", "value": 1}, {"key": "b", "value": 2}]],
dtype=Map(pl.String(), pl.Int64()),
)
right = pl.Series(
"r",
[[{"key": "a", "value": 99}, {"key": "c", "value": 3}]],
dtype=Map(pl.String(), pl.Int64()),
)
pair = pl.DataFrame([left, right])
pair.select(pl.col("l").map.merge(pl.col("r")))
# [{"a": 99, "b": 2, "c": 3}]
# set operations
pair.select(pl.col("l").map.intersection(pl.col("r"))) # keys in both
pair.select(pl.col("l").map.difference(pl.col("r"))) # keys only in left
# strip Map -> List(Struct)
df.select(pl.col("m").map.entries())
# from_entries is the inverse
entries = pl.Series(
"e",
[[{"key": "a", "value": 1}, {"key": "b", "value": 2}, {"key": "a", "value": 3}]],
dtype=pl.List(pl.Struct({"key": pl.String, "value": pl.Int64})),
)
pl.DataFrame([entries]).select(pl.col("e").map.from_entries()) # {"a": 3, "b": 2}
# Series iteration yields dicts
for d in ser.map:
print(d) # {"a": 1, "b": 2}, {"x": 10}
# arrow roundtrip
table = pa.table({"m": pa.array([[("a", 1)]], type=pa.map_(pa.string(), pa.int64()))})
df = from_arrow(table) # Map(String, Int64) dtype preserved
table2 = to_arrow(df)
# lazy scanning from an arrow source
lf = scan_arrow(lambda: [table])
result = lf.collect()
Caveats
- Extension types — used to wrap the underlying
List(Struct)storage with a semanticMapdtype, are not yet stabilized and may change across Polars releases. pl.dtype_of— used to efficiently cast to the extension type after some operations is also unstable.- GIL - is required to automatically wrap an expression as the extension type, and so operations which could change the underlying key or value types will briefly lock the GIL to do the cast. This may also prevent the polars engine from reasoning about the type.
- Large offsets — Arrow's
map<>type uses only 32-bit offsets, so exporting a Polars map backed by aLargeListwhose offsets don't fit in au32will error. Arrow has no large-offset map type.
Migrating to native pl.Map
Map(pl.String(), pl.Int64()) becomes pl.Map(pl.String, pl.Int64), .map.from_entries()
becomes .list.to_map(), and the Arrow helpers become pl.from_arrow / .to_arrow().
The remaining methods have no native counterpart; write them as .map.entries(), a
list.eval, and .list.to_map() when a map is rebuilt.
m.map.entries().list.eval(pl.element().struct["key"]) # keys
pl.concat_list(l.map.entries(), r.map.entries()).list.to_map() # merge
Metadata
Release files for polars-map 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_map-0.3.0.tar.gz | 73.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| polars_map-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 87.1 kB
Release files / polars_map-0.3.0.tar.gz
| Download URL | polars_map-0.3.0.tar.gz |
|---|---|
| Size | 73.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff4d6490f619fc094dc32c5ee74cf73db393b13b2282c18960f7d283d6939d24
|
|
BLAKE2b-256 checksum How to use checksums |
4e4229682383b98c0fa631b0f29a27f25d51df5abf1e5509bd77991489bc437d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency logRelease files / polars_map-0.3.0-py3-none-any.whl
| Download URL | polars_map-0.3.0-py3-none-any.whl |
|---|---|
| Size | 14.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f6dfb79d3ddab7e733a5f2dcf878b7f618caa5191b80c0f32ad742d5045bd35
|
|
BLAKE2b-256 checksum How to use checksums |
1b63d1d11e789e8111e2f0fe0c1bfd2d0ed33aa3a9ae65884fd449da1b5e0f24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency log