Python Polars 滚动计数

标签 python python-3.x dataframe rolling-computation python-polars

Polars中有一些已知的滚动函数,即rolling_mean()、rolling_apply()和rolling_max()。但是,如果我想统计每个窗口中某个值出现的次数,该怎么做?

假设我们现在有一个 LazyFrame:

df = pl.LazyFrame({"Date": ["2023-01-01", "2023-01-02", "2023-01-03", "2023-01-05", "2023-01-10", "2023-01-11", "2023-01-12"], "Pattern": [True, True, False, True, False, False, True]})
┌────────────┬─────────┐
│ Date       ┆ Pattern │
│ ---        ┆ ---     │
│ str        ┆ bool    │
╞════════════╪═════════╡
│ 2023-01-01 ┆ true    │
│ 2023-01-02 ┆ true    │
│ 2023-01-03 ┆ false   │
│ 2023-01-05 ┆ true    │
│ 2023-01-10 ┆ false   │
│ 2023-01-11 ┆ false   │
│ 2023-01-12 ┆ true    │
└────────────┴─────────┘

对于n = 3且pattern = True,期望的结果是:

┌────────────┬─────────┐
│ Date       ┆ Count   │
│ ---        ┆ ---     │
│ str        ┆ int     │
╞════════════╪═════════╡
│ 2023-01-01 ┆ null    │
│ 2023-01-02 ┆ null    │
│ 2023-01-03 ┆ 2       │
│ 2023-01-05 ┆ 2       │
│ 2023-01-10 ┆ 1       │
│ 2023-01-11 ┆ 1       │
│ 2023-01-12 ┆ 1       │
└────────────┴─────────┘

我尝试在 Pattern 列上使用rolling_sum(),但由于我的列是 bool 类型,使用此类函数只会产生错误。

在 pandas 中,这可以通过以下方式实现:

df["Pattern"].apply(lambda x: x == True).rolling(3, min_periods = 0).sum()

使用极坐标的正确方法是什么?并且,如何将解决方案推广到 bool 值 True 值以外的列,例如 False 和分类数据?

最佳答案

I have tried using rolling_sum() over the column Pattern, yet since my column is of Boolean type, using such functions would only yield an error.

您可以使用rolling_sum,只需首先使用Expr.cast将 bool 表达式转换为数字类型即可(False 值转换为 0True 值转换为 1)。

n = 3
pattern_value = True

res = df.with_columns(
    (pl.col('Pattern') == pattern_value).cast(pl.UInt8).rolling_sum(window_size=n)
)

对于 pattern_value = True 使用 (pl.col('Pattern') == pattern_value) 是多余的,您可以只使用 pl.col('模式').cast(pl.UInt8).

输出:

>>> res

shape: (7, 2)
┌────────────┬─────────┐
│ Date       ┆ Pattern │
│ ---        ┆ ---     │
│ str        ┆ u8      │
╞════════════╪═════════╡
│ 2023-01-01 ┆ null    │
│ 2023-01-02 ┆ null    │
│ 2023-01-03 ┆ 2       │
│ 2023-01-05 ┆ 2       │
│ 2023-01-10 ┆ 1       │
│ 2023-01-11 ┆ 1       │
│ 2023-01-12 ┆ 1       │
└────────────┴─────────┘

In pandas, this can be achieved by:

df["Pattern"].apply(lambda x: x == True).rolling(3, min_periods = 0).sum()

请注意,使用 min_periods = 0 不会产生上述输出。 Expr.rolling_sum如果需要,该方法还接受 min_periods 参数(默认为窗口大小)。例如


>>> df.with_columns(
    pl.col('Pattern').cast(pl.UInt8).rolling_sum(window_size=3, min_periods=0)
)

shape: (7, 2)
┌────────────┬─────────┐
│ Date       ┆ Pattern │
│ ---        ┆ ---     │
│ str        ┆ u8      │
╞════════════╪═════════╡
│ 2023-01-01 ┆ 1       │
│ 2023-01-02 ┆ 2       │
│ 2023-01-03 ┆ 2       │
│ 2023-01-05 ┆ 2       │
│ 2023-01-10 ┆ 1       │
│ 2023-01-11 ┆ 1       │
│ 2023-01-12 ┆ 1       │
└────────────┴─────────┘

关于Python Polars 滚动计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75830372/

相关文章:

python - 委托(delegate)给 Python 中的 dict 类

javascript - 将 Python None 转换为 JavaScript null

python - 如何停止在 Django 2.* 管理面板中记录最近的操作和历史记录?

python - 为什么用 universal_newlines 打开子进程会导致 unicode 解码异常?

python - 在 Pandas 数据框列中添加多个常量值

r - 如何提取数据框列表中的列名称?

python - Django休息框架: Display object only for specific choice

python - Pandas:查找特定列不为 NA 但所有其他列为 NA 的行

python - 无状态使用 tkinter.Canvas

python - 在 Python 中为每一列使用相同的列表创建 Pandas DataFrame