@@ -62,21 +62,28 @@ uv add --editable "/path/to/raffalib-python[pandas,polars]"
6262### Logging changes in a pandas pipeline
6363
6464``` python
65+ import numpy as np
6566import pandas as pd
6667import raffalib
6768import raffalib.pandas # registers the `.raffa` accessor
6869
6970logger = raffalib.create_logger(rich = False , fmt = " {message} " )
7071
71- df = pd.read_csv(" https://raw.githubusercontent.com/allisonhorst/palmerpenguins/refs/heads/main/inst/extdata/penguins.csv" )
72+ df = pd.DataFrame(
73+ {
74+ " species" : [" Adelie" , " Adelie" , " Adelie" , " Gentoo" , " Gentoo" , " Chinstrap" ],
75+ " bill_depth_mm" : [18.7 , np.nan, 18.0 , np.nan, 16.3 , 17.9 ],
76+ " body_mass_g" : [3750.0 , 3800.0 , np.nan, 4500.0 , 5700.0 , 3500.0 ],
77+ }
78+ )
7279
7380# Shape changes are logged automatically
7481_ = df.raffa.startlog().dropna(subset = [" bill_depth_mm" ]).raffa.endlog(timeit = False )
75- # -> Removed 2/344 (0.58 %) rows.
82+ # -> Removed 2/6 (33.33 %) rows.
7683
7784# Pass clone=True to also detect value-level changes when the shape is unchanged
7885_ = df.raffa.startlog(clone = True ).fillna(0 ).raffa.endlog(timeit = False )
79- # -> Changed 19/2,752 (0.69 %) values.
86+ # -> Changed 3/18 (16.67 %) values.
8087```
8188
8289### The same with polars
@@ -88,10 +95,16 @@ import raffalib.polars # registers the `.raffa` namespace
8895
8996logger = raffalib.create_logger(rich = False , fmt = " {message} " )
9097
91- df = pl.read_csv(" https://raw.githubusercontent.com/allisonhorst/palmerpenguins/refs/heads/main/inst/extdata/penguins.csv" )
98+ df = pl.DataFrame(
99+ {
100+ " species" : [" Adelie" , " Adelie" , " Adelie" , " Gentoo" , " Gentoo" , " Chinstrap" ],
101+ " bill_depth_mm" : [18.7 , None , 18.0 , None , 16.3 , 17.9 ],
102+ " body_mass_g" : [3750.0 , 3800.0 , None , 4500.0 , 5700.0 , 3500.0 ],
103+ }
104+ )
92105
93106_ = df.raffa.startlog().filter(pl.col(" species" ) == " Adelie" ).raffa.endlog(timeit = False )
94- # -> Removed 192/344 (55.81 %) rows.
107+ # -> Removed 3/6 (50.00 %) rows.
95108```
96109
97110Both backends share the same ` startlog(clone=False) ` / ` endlog(custom_msg=None, timeit=True) `
@@ -103,6 +116,9 @@ Both accessors expose the same `join()` wrapper — over `pd.DataFrame.merge` fo
103116pandas and ` pl.DataFrame.join ` for polars — with identical logging output:
104117
105118``` python
119+ df1 = pd.DataFrame({" A" : [" a1" , " a2" , " a3" , " a4" ], " B" : [" b1" , " b2" , " b3" , " b4" ]})
120+ df2 = pd.DataFrame({" A" : [" a1" , " a2" , " a3" , " a5" , " a6" ], " C" : [" c1" , " c2" , " c3" , " c5" , " c6" ]})
121+
106122out = df1.raffa.join(df2, on = " A" , how = " left" )
107123# Total rows in output table: 4
108124# From left only: 1/4 (25.00%)
0 commit comments