极坐标分组+ value_counts

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

我需要一些有关极地的帮助:

我有一个带有分类值列的数据框

┌───────────────────┬──────────────┬────────┐
│ session_id        ┆ elapsed_time ┆ fqid   │
│ ---               ┆ ---          ┆ ---    │
│ i64               ┆ i32          ┆ cat    │
╞═══════════════════╪══════════════╪════════╡
│ 20090312431273200 ┆ 0            ┆ intro  │
│ 20090312431273200 ┆ 1323         ┆ gramps │
│ 20090312431273200 ┆ 831          ┆ gramps │
│ 20090312431273200 ┆ 1147         ┆ gramps │
│ …                 ┆ …            ┆ …      │
│ 20090312431273200 ┆ 5197         ┆ teddy  │
│ 20090312431273200 ┆ 6180         ┆ teddy  │
│ 20090312431273200 ┆ 7014         ┆ teddy  │
│ 20090312431273200 ┆ 7946         ┆ teddy  │
└───────────────────┴──────────────┴────────┘

我想将 fqid 列转换为如下所示:

┌───────────────────┬─────────────┬────────────┬────────────┐
│ session_id        ┆ fqid_gramps ┆ fqid_intro ┆ fqid_teddy │
│ ---               ┆ ---         ┆ ---        ┆ ---        │
│ i64               ┆ i32         ┆ i32        ┆ i32        │
╞═══════════════════╪═════════════╪════════════╪════════════╡
│ 20090312431273200 ┆ 1           ┆ 1          ┆ 4          │
└───────────────────┴─────────────┴────────────┴────────────┘

也就是说,我想:

  • session_id
  • 分组
  • fqid
    ,
  • 上创建 value_counts()
  • 重命名列,使其成为 'fqid_' +
    category
    ,
  • 将它们变成列(转置),
  • 将它们添加到结果中。

从技术上讲,我可以通过使用类似的东西来实现这一点而无需groupby

column_values = train['fqid'].value_counts().with_columns(pl.concat_str(pl.lit('fqid' + '_').alias('fqid'), pl.col('fqid').cast(pl.Utf8))).transpose()
column_values = column_values.rename(column_values.head(1).to_dicts().pop()).slice(1)

但是当我尝试用

train['fqid']
替换
pl.col('fqid')
并制作
groupby('session_id').aggregate(func('fqid'))
来创建聚合函数时,它只会给我带来像
AttributeError: 'Expr' object has no attribute 'with_columns'
这样的错误。

您能否建议进行此操作的正确方法?

python group-by python-polars
1个回答
4
投票

开始
train=pl.from_repr(
     """┌───────────────────┬──────────────┬────────┐
        │ session_id        ┆ elapsed_time ┆ fqid   │
        │ ---               ┆ ---          ┆ ---    │
        │ i64               ┆ i32          ┆ cat    │
        ╞═══════════════════╪══════════════╪════════╡
        │ 20090312431273200 ┆ 0            ┆ intro  │
        │ 20090312431273200 ┆ 1323         ┆ gramps │
        │ 20090312431273200 ┆ 831          ┆ gramps │
        │ 20090312431273200 ┆ 1147         ┆ gramps │
        │ 20090312431273200 ┆ 5197         ┆ teddy  │
        │ 20090312431273200 ┆ 6180         ┆ teddy  │
        │ 20090312431273200 ┆ 7014         ┆ teddy  │
        │ 20090312431273200 ┆ 7946         ┆ teddy  │
        └───────────────────┴──────────────┴────────┘""")

我们能做到

(
    train
        .group_by(
            (piv_idx:='session_id'),
            (len_id:='fqid'),
            maintain_order=True) 
        .len()
        .pivot(values='len',
               index=piv_idx,
               columns=len_id,
               aggregate_function='first')
        .select(
            piv_idx,
            pl.exclude(piv_idx).name.prefix(f"{len_id}_")
            )
)

shape: (1, 4)
┌───────────────────┬────────────┬─────────────┬────────────┐
│ session_id        ┆ fqid_intro ┆ fqid_gramps ┆ fqid_teddy │
│ ---               ┆ ---        ┆ ---         ┆ ---        │
│ i64               ┆ u32        ┆ u32         ┆ u32        │
╞═══════════════════╪════════════╪═════════════╪════════════╡
│ 20090312431273200 ┆ 1          ┆ 3           ┆ 4          │
└───────────────────┴────────────┴─────────────┴────────────┘

由于您想要 fqids 的计数(现在是 len),因此您需要将其包含在

group_by
中。接下来,我们执行
pivot
以使结果更宽。数据透视表的输出不会保留原始列名称,因此我们必须手动将其添加回来。我们在
select
中执行此操作,首先获取
session_id
,然后将除
session_id
之外的每一列添加到前缀“fqid_”,以获得最终所需的结果。

顺便说一句,我没有使用

value_counts
,因为它返回一个结构列表,所以我们不能这样做,例如,
train.select(pl.col('fqid').value_counts().over('session_id'))

我使用 walrus 运算符 将列名称分配给

group_by
中的变量,这样您只需在一处更改列而无需重复自己。在枢轴中并选择。

© www.soinside.com 2019 - 2024. All rights reserved.