Python - Polars 库中的滚动索引?

问题描述 投票:0回答:1

我想问问是否有人知道如何在极坐标中进行滚动索引? 我个人尝试了一些对我不起作用的解决方案(我将在下面展示它们):

我想要做什么按名称对过去 X 天内出现的次数进行索引 示例:假设我想对过去 2 天内发生的事件建立索引:

姓名 日期 柜台
约翰 1 月 23 日 1
约翰 1 月 23 日 2
约翰 1 月 23 日 3
约翰 1 月 23 日 4
约翰 2 1 月 23 日 5
约翰 2 1 月 23 日 6
约翰 2 1 月 23 日 7
约翰 2 1 月 23 日 8
约翰 23 年 1 月 3 日 5
约翰 23 年 1 月 3 日 6
新人 1 月 23 日 1

在这种情况下,计数器从过去 X 天开始重置为“1”(例如,对于 23 年 1 月 3 日,它从 23 年 1 月 2 日开始重置为“1”),或者如果检测到新名称

我尝试过的

df.groupby_rolling(index_column='Date', period='2d', by='Name', check_sorted=False).agg((pl.col("Date").rank(method='ordinal')).alias("Counter"))

上面不起作用,因为它输出:

姓名 日期 柜台
约翰 1 月 23 日 1,2,3,4
约翰 1 月 23 日 1,2,3,4
约翰 1 月 23 日 1,2,3,4
约翰 1 月 23 日 1,2,3,4
约翰 2 1 月 23 日 1...8
约翰 2 1 月 23 日 1...8
约翰 2 1 月 23 日 1...8
约翰 2 月 23 日 1...8
约翰 23 年 1 月 3 日 1...6
约翰 23 年 1 月 3 日 1...6
新人 1 月 23 日 1
df.with_columns( Counter=pl.col("mask").rolling_sum(window_size='2d', by="Date") )

我创建了一列“Mask”,它只是一列“1”,并尝试对它们求和,但它输出:

姓名 日期 面膜 柜台
约翰 1 月 23 日 1 4
约翰 1 月 23 日 1 4
约翰 1 月 23 日 1 4
约翰 1 月 23 日 1 4
约翰 2 1 月 23 日 1 8
约翰 2 1 月 23 日 1 8
约翰 2 1 月 23 日 1 8
约翰 2 1 月 23 日 1 8
约翰 23 年 1 月 3 日 1 6
约翰 23 年 1 月 3 日 1 6

它也无法正确处理“New Guy”,因为rolling_sum不能通过=“Name”,“Date”来完成

df.with_columns(Counter = pl.col("Date").rank(method='ordinal').over(["Name", "Date"]) )

上述代码工作正常,但只能用于同一天内的索引(即 period="1d")

附加说明:我也在 Excel 中执行了此操作,并且还使用了使用“for”循环的暴力/原始方法。两者都工作得很好,但是它们在处理大量数据时遇到了困难。

我读到的内容: 一些有助于回答的参考文献:(大多数都不起作用,因为它们有固定的滚动窗口而不是按“日期”的动态窗口)

如何在Polars 0.19版本中实现滚动排名

https://github.com/pola-rs/polars/issues/4808

如何在Python中的极坐标中按天按小时进行group_by_rolling分组?

如何在极坐标中分组和滚动?

https://docs.pola.rs/py-polars/html/reference/series/api/polars.Series.rank.html

https://docs.pola.rs/py-polars/html/reference/dataframe/api/polars.DataFrame.groupby_rolling.html

python pandas group-by python-polars data-wrangling
1个回答
0
投票

我对您的预期结果有点不确定,但我建议您执行以下操作:

import polars as pl

data = {
    "Name": ["John", "John", "John", "John", "John", "John", "John", "John", "John", "John", "New Guy"],
    "Date": ["1 Jan 23", "1 Jan 23", "1 Jan 23", "1 Jan 23", "2 Jan 23", "2 Jan 23", "2 Jan 23", "2 Jan 23", "3 Jan 23", "3 Jan 23", "1 Jan 23"]
}

df = pl.DataFrame(data)
df = df.with_columns(pl.col("Date").str.strptime(pl.Date, "%d %b %y"))
df = df.sort(["Name", "Date"])
df = df.with_columns(
    (pl.col("Date").diff().cast(pl.Int32).fill_null(1) != 0).cumsum().over("Name").alias("group_id")
)
result = df.with_columns(
    pl.count().over(["Name", "group_id"]).alias("Counter")
)

print(result)

这给了你

shape: (11, 4)
┌─────────┬────────────┬──────────┬─────────┐
│ Name    ┆ Date       ┆ group_id ┆ Counter │
│ ---     ┆ ---        ┆ ---      ┆ ---     │
│ str     ┆ date       ┆ u32      ┆ u32     │
╞═════════╪════════════╪══════════╪═════════╡
│ John    ┆ 2023-01-01 ┆ 1        ┆ 4       │
│ John    ┆ 2023-01-01 ┆ 1        ┆ 4       │
│ John    ┆ 2023-01-01 ┆ 1        ┆ 4       │
│ John    ┆ 2023-01-01 ┆ 1        ┆ 4       │
│ John    ┆ 2023-01-02 ┆ 2        ┆ 4       │
│ …       ┆ …          ┆ …        ┆ …       │
│ John    ┆ 2023-01-02 ┆ 2        ┆ 4       │
│ John    ┆ 2023-01-02 ┆ 2        ┆ 4       │
│ John    ┆ 2023-01-03 ┆ 3        ┆ 2       │
│ John    ┆ 2023-01-03 ┆ 3        ┆ 2       │
│ New Guy ┆ 2023-01-01 ┆ 1        ┆ 1       │
└─────────┴────────────┴──────────┴─────────┘
© www.soinside.com 2019 - 2024. All rights reserved.