代码之家  ›  专栏  ›  技术社区  ›  ldrg

在波拉斯语组内排名?

  •  1
  • ldrg  · 技术社区  · 7 月前

    我有一个Polars数据帧,如下所示:

    c1 c2 c3
    1.
    1.
    b 1.
    c 1.
    d 1.
    d b 1.

    我试图给c1中的每组(c2,c3)分配一个数字,所以看起来是这样的:

    c1 c2 c3 等级
    1. 0
    1. 0
    b 1. 1.
    c 1. 2.
    d 1. 0
    d b 1. 1.

    我该如何做到这一点?

    我知道如何进行全球排名:

    df.join(
        df.select(["c1", "c2", "c3"])
        .unique()
        .with_columns(rank=pl.int_range(1, pl.len() + 1),
        on=["c1", "c2", "c3"]
    )
    

    但这是一个全球排名,而不是c1组的排名。我还想知道是否可以用over()代替groupby/join模式来实现这一点。

    1 回复  |  直到 7 月前
        1
  •  3
  •   Dogbert    7 月前

    创建列的结构 c2 , c3 使用 pl.struct("c2", "c3") ,计算稠密秩 c1 ,然后减去1,因为默认情况下排名从1开始:

    pl.struct("c2", "c3").rank("dense").over("c1") - 1
    

    完整代码:

    import polars as pl
    
    df = pl.DataFrame(
        {
            "c1": ["a", "a", "a", "a", "d", "d"],
            "c2": ["a", "a", "b", "c", "a", "b"],
            "c3": [1, 1, 1, 1, 1, 1],
        }
    )
    
    df2 = df.with_columns(rank=pl.struct("c2", "c3").rank("dense").over("c1") - 1)
    
    print(df2)
    

    输出

    ┌─────┬─────┬─────┬──────┐
    │ c1  ┆ c2  ┆ c3  ┆ rank │
    │ --- ┆ --- ┆ --- ┆ ---  │
    │ str ┆ str ┆ i64 ┆ u32  │
    ╞═════╪═════╪═════╪══════╡
    │ a   ┆ a   ┆ 1   ┆ 0    │
    │ a   ┆ a   ┆ 1   ┆ 0    │
    │ a   ┆ b   ┆ 1   ┆ 1    │
    │ a   ┆ c   ┆ 1   ┆ 2    │
    │ d   ┆ a   ┆ 1   ┆ 0    │
    │ d   ┆ b   ┆ 1   ┆ 1    │
    └─────┴─────┴─────┴──────┘