Search code examples
pythonpython-3.xalgorithmnumpypython-polars

How to extinguish cycle in my code when calculating EMWA?


I'm calculating EWMA values for array of streamflow, and code is like below:

import polars as pl
import numpy as np

streamflow_data = np.arange(0, 20, 1)
adaptive_alphas = np.concatenate([np.repeat(0.3, 10), np.repeat(0.6, 10)])
streamflow_series = pl.Series(streamflow_data)
ewma_data = np.zeros_like(streamflow_data)
for i in range(1, len(streamflow_series)):
    current_alpha = adaptive_alphas[i]
    ewma_data[i] = streamflow_series[:i+1].ewm_mean(alpha=current_alpha)[-1]
# When set dtype of ewma_data to float when initial it, output is like this
Output: [0  0.58823529  1.23287671  1.93051717  2.67678771  3.46668163,  4.29488309  5.1560635   6.04512113  6.95735309  9.33379473 10.33353466, 11.33342058 12.33337091 13.33334944 14.33334021 15.33333625 16.33333457, 17.33333386 18.33333355]

# When I don't point dtype of ewma_data and dtype of streamflow_data is int, output will be floored
Output: [0  0  1  1  2  3  4  5  6  6  9 10 11 12 13 14 15 16 17 18]

But when length of streamflow_data is very big (such as >100000), this code will become very slow.

So how can I extinguish for in my code and don't influence its result?

Hope for your reply.


Solution

  • If you have only few alpha values and/or have some condition on which alpha should be used for which row, you could use pl.coalesce(), pl.when() and pl.Expr.ewm_mean():

    df = pl.DataFrame({
        "adaptive_alpha": np.concatenate([np.repeat(0.3, 10), np.repeat(0.6, 10)]),
        "streamflow": np.arange(0, 20, 1)
    })
    
    df.with_columns(
        pl.coalesce(
            pl.when(pl.col.adaptive_alpha == alpha)
            .then(pl.col.streamflow.ewm_mean(alpha = alpha))
            for alpha in df["adaptive_alpha"].unique()
        ).alias("ewma")
    ).with_columns(ewma_int = pl.col.ewma.cast(pl.Int32))
    
    shape: (20, 4)
    ┌────────────────┬────────────┬───────────┬──────────┐
    │ adaptive_alpha ┆ streamflow ┆ ewma      ┆ ewma_int │
    │ ---            ┆ ---        ┆ ---       ┆ ---      │
    │ f64            ┆ i64        ┆ f64       ┆ i32      │
    ╞════════════════╪════════════╪═══════════╪══════════╡
    │ 0.3            ┆ 0          ┆ 0.0       ┆ 0        │
    │ 0.3            ┆ 1          ┆ 0.588235  ┆ 0        │
    │ 0.3            ┆ 2          ┆ 1.232877  ┆ 1        │
    │ 0.3            ┆ 3          ┆ 1.930517  ┆ 1        │
    │ 0.3            ┆ 4          ┆ 2.676788  ┆ 2        │
    │ …              ┆ …          ┆ …         ┆ …        │
    │ 0.6            ┆ 15         ┆ 14.33334  ┆ 14       │
    │ 0.6            ┆ 16         ┆ 15.333336 ┆ 15       │
    │ 0.6            ┆ 17         ┆ 16.333335 ┆ 16       │
    │ 0.6            ┆ 18         ┆ 17.333334 ┆ 17       │
    │ 0.6            ┆ 19         ┆ 18.333334 ┆ 18       │
    └────────────────┴────────────┴───────────┴──────────┘