我需要一些有关极地的帮助:
我有一个带有分类值列的数据框
┌───────────────────┬──────────────┬────────┐
│ 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
,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'
这样的错误。
您能否建议进行此操作的正确方法?
从
开始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
中的变量,这样您只需在一处更改列而无需重复自己。在枢轴中并选择。