I want to calculate a median over an irregular pandas series.
In particular, I want to calculate the median first based on the first X-days and later based on the following X-days.
I did code the following working example. In there, I generate two columns, one median_-2days which lists the median based on the previous two days and one median_+2days which does the same based on the next 2 days.
import numpy as np
import pandas as pd
def dummy_data():
idx = np.array([pd.Timestamp(year=2021, month=1, day=1),
pd.Timestamp(year=2021, month=1, day=2),
pd.Timestamp(year=2021, month=1, day=3),
pd.Timestamp(year=2021, month=1, day=5),
pd.Timestamp(year=2021, month=1, day=6),
pd.Timestamp(year=2021, month=1, day=8),
pd.Timestamp(year=2021, month=1, day=9),
pd.Timestamp(year=2021, month=1, day=10),
])
data = np.array([1, 2, 3, 5, 6, 8, 9, 10])
return pd.DataFrame(data, index=idx, columns=["l"])
def rolling_median_irregular(ds, left, right):
res = pd.Series(index=ds.index)
for t in ds.index:
val = ds.loc[(ds.index >= t - left) & (ds.index <= t + right)].median()
res.loc[t] = val
return res
if __name__ == "__main__":
df = dummy_data()
df["median_-2days"] = rolling_median_irregular(df["l"], left=pd.Timedelta(days=2), right=pd.Timedelta(days=0))
df["median_+2days"] = rolling_median_irregular(df["l"], left=pd.Timedelta(days=0), right=pd.Timedelta(days=2))
However, I feel like I'm reinventing the wheel. I would prefer to use the built-in rolling function to have a more general approach where I can also use different functions (like .sum() or .mean()) and different window types.
Is it even possible to do this with the built-in functions or do I have to subclass a BaseIndexer? If this is the case, how would this look like?