import sys
sys.version_info
sys.version_info(major=3, minor=12, micro=5, releaselevel='final', serial=0)
Dheepak Krishnamurthy
August 25, 2024
This is a short comparison of idiomatic pandas
, polars
and ibis
, all using method chaining.
sys.version_info(major=3, minor=12, micro=5, releaselevel='final', serial=0)
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ name ┃ height ┃ mass ┃ hair_color ┃ skin_color ┃ eye_color ┃ birth_year ┃ sex ┃ gender ┃ homeworld ┃ species ┃ films ┃ vehicles ┃ starships ┃ ┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ │ string │ int64 │ float64 │ string │ string │ string │ float64 │ string │ string │ string │ string │ string │ string │ string │ ├────────────────────┼────────┼─────────┼───────────────┼─────────────┼───────────┼────────────┼────────┼───────────┼───────────┼─────────┼────────┼──────────┼───────────┤ │ Luke Skywalker │ 172 │ 77.0 │ blond │ fair │ blue │ 19.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ C-3PO │ 167 │ 75.0 │ NULL │ gold │ yellow │ 112.0 │ none │ masculine │ Tatooine │ Droid │ NULL │ NULL │ NULL │ │ R2-D2 │ 96 │ 32.0 │ NULL │ white, blue │ red │ 33.0 │ none │ masculine │ Naboo │ Droid │ NULL │ NULL │ NULL │ │ Darth Vader │ 202 │ 136.0 │ none │ white │ yellow │ 41.9 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Leia Organa │ 150 │ 49.0 │ brown │ light │ brown │ 19.0 │ female │ feminine │ Alderaan │ Human │ NULL │ NULL │ NULL │ │ Owen Lars │ 178 │ 120.0 │ brown, grey │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Beru Whitesun Lars │ 165 │ 75.0 │ brown │ light │ blue │ 47.0 │ female │ feminine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ R5-D4 │ 97 │ 32.0 │ NULL │ white, red │ red │ NULL │ none │ masculine │ Tatooine │ Droid │ NULL │ NULL │ NULL │ │ Biggs Darklighter │ 183 │ 84.0 │ black │ light │ brown │ 24.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Obi-Wan Kenobi │ 182 │ 77.0 │ auburn, white │ fair │ blue-gray │ 57.0 │ male │ masculine │ Stewjon │ Human │ NULL │ NULL │ NULL │ │ … │ … │ … │ … │ … │ … │ … │ … │ … │ … │ … │ … │ … │ … │ └────────────────────┴────────┴─────────┴───────────────┴─────────────┴───────────┴────────────┴────────┴───────────┴───────────┴─────────┴────────┴──────────┴───────────┘
import re
M = 100
_df = (
df
.to_pandas()
.rename(lambda col: re.sub(r'(?<!^)(?=[A-Z])', '_', col).lower(), axis=1)
.query("height > 100")
.query("mass > @M")
.query('hair_color.str.contains("brown") == True') # some values can be `None` so explicit True required
.query("sex.notna()")
.assign(hair_color = lambda c: c.hair_color.str.split(','))
.explode("hair_color")
.query("birth_year.notna()")
)
ibis.pandas.connect({'_df': _df}).table('_df')
┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ name ┃ height ┃ mass ┃ hair_color ┃ skin_color ┃ eye_color ┃ birth_year ┃ sex ┃ gender ┃ homeworld ┃ species ┃ films ┃ vehicles ┃ starships ┃ ┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ │ string │ float64 │ float64 │ string │ string │ string │ float64 │ string │ string │ string │ string │ null │ null │ null │ ├───────────┼─────────┼─────────┼────────────┼────────────┼───────────┼────────────┼────────┼───────────┼───────────┼─────────┼───────┼──────────┼───────────┤ │ Owen Lars │ 178.0 │ 120.0 │ brown │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Owen Lars │ 178.0 │ 120.0 │ grey │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Chewbacca │ 228.0 │ 112.0 │ brown │ unknown │ blue │ 200.0 │ male │ masculine │ Kashyyyk │ Wookiee │ NULL │ NULL │ NULL │ └───────────┴─────────┴─────────┴────────────┴────────────┴───────────┴────────────┴────────┴───────────┴───────────┴─────────┴───────┴──────────┴───────────┘
import re
import polars as pl
M = 100
_df = (
df
.to_polars()
.rename(lambda col: re.sub(r'(?<!^)(?=[A-Z])', '_', col).lower())
.filter(pl.col("height") > 100)
.filter(pl.col("mass") > M)
.filter(pl.col("hair_color").str.contains("brown"))
.filter(pl.col("sex").is_not_null())
.with_columns(pl.col("hair_color").str.split(",").alias("hair_color"))
.explode(pl.col("hair_color"))
.filter(pl.col("birth_year").is_not_null())
)
ibis.polars.connect({'_df': _df}).table('_df')
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ name ┃ height ┃ mass ┃ hair_color ┃ skin_color ┃ eye_color ┃ birth_year ┃ sex ┃ gender ┃ homeworld ┃ species ┃ films ┃ vehicles ┃ starships ┃ ┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ │ string │ int64 │ float64 │ string │ string │ string │ float64 │ string │ string │ string │ string │ string │ string │ string │ ├───────────┼────────┼─────────┼────────────┼────────────┼───────────┼────────────┼────────┼───────────┼───────────┼─────────┼────────┼──────────┼───────────┤ │ Owen Lars │ 178 │ 120.0 │ brown │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Owen Lars │ 178 │ 120.0 │ grey │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Chewbacca │ 228 │ 112.0 │ brown │ unknown │ blue │ 200.0 │ male │ masculine │ Kashyyyk │ Wookiee │ NULL │ NULL │ NULL │ └───────────┴────────┴─────────┴────────────┴────────────┴───────────┴────────────┴────────┴───────────┴───────────┴─────────┴────────┴──────────┴───────────┘
M = 100
_df = (
df
.rename("snake_case")
.filter(_.height > 100)
.filter(_.mass > M)
.filter(_.hair_color.contains("brown"))
.filter(_.sex.notnull())
.mutate(hair_color = _.hair_color.split(","))
.unnest(_.hair_color)
.drop_null(_.birth_year)
)
_df
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ name ┃ height ┃ mass ┃ hair_color ┃ skin_color ┃ eye_color ┃ birth_year ┃ sex ┃ gender ┃ homeworld ┃ species ┃ films ┃ vehicles ┃ starships ┃ ┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━┩ │ string │ int64 │ float64 │ string │ string │ string │ float64 │ string │ string │ string │ string │ string │ string │ string │ ├───────────┼────────┼─────────┼────────────┼────────────┼───────────┼────────────┼────────┼───────────┼───────────┼─────────┼────────┼──────────┼───────────┤ │ Owen Lars │ 178 │ 120.0 │ brown │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Owen Lars │ 178 │ 120.0 │ grey │ light │ blue │ 52.0 │ male │ masculine │ Tatooine │ Human │ NULL │ NULL │ NULL │ │ Chewbacca │ 228 │ 112.0 │ brown │ unknown │ blue │ 200.0 │ male │ masculine │ Kashyyyk │ Wookiee │ NULL │ NULL │ NULL │ └───────────┴────────┴─────────┴────────────┴────────────┴───────────┴────────────┴────────┴───────────┴───────────┴─────────┴────────┴──────────┴───────────┘
@online{krishnamurthy2024,
author = {Krishnamurthy, Dheepak},
title = {Pandas Vs {Polars} Vs Ibis},
date = {2024-08-25},
url = {https://kdheepak.com/blog/pandas-vs-polars-vs-ibis/},
langid = {en}
}