在 Polars 中获取百分比计数的最佳方法

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

我经常需要计算变量的百分比计数。例如下面的数据框

df = pl.DataFrame({"person": ["a", "a", "b"], 
                   "value": [1, 2, 3]})

我想返回这样的数据框:

百分比
a 0.667
b 0.333

我一直在做以下事情,但我忍不住认为必须有一种更有效/极地的方法来做到这一点

n_rows = len(df)

(   
    df
    .with_column(pl.lit(1)
    .alias('percent'))
    .groupby('person')
    .agg([pl.sum('percent') / n_rows])
)
python-polars
3个回答
5
投票

polars.count
将在这里提供帮助。当不带参数调用时,
polars.count
返回特定上下文中的行数。

(
    df
    .groupby("person")
    .agg([pl.count().alias("count")])
    .with_columns((pl.col("count") / pl.sum("count")).alias("percent_count"))
)
shape: (2, 3)
┌────────┬───────┬───────────────┐
│ person ┆ count ┆ percent_count │
│ ---    ┆ ---   ┆ ---           │
│ str    ┆ u32   ┆ f64           │
╞════════╪═══════╪═══════════════╡
│ a      ┆ 2     ┆ 0.666667      │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ b      ┆ 1     ┆ 0.333333      │
└────────┴───────┴───────────────┘

1
投票

使用

Series
方法
.value_counts

import polars as pl

df = pl.DataFrame({
    'person': ['a', 'a', 'b', None, 'b'],
    'value': [1, 2, 3, 2, 3]
})
df['person'].value_counts(sort=True).select(
    pl.col('person'),
    pl.col('counts'),
    (pl.col('counts')/pl.col('counts').sum() * 100).round(2).alias('perc')
)

或者

df['person'].value_counts(sort=True).select(
    pl.col('person'),
    pl.col('counts'),
    pl.col('counts').apply(lambda x: x/df.shape[0]*100).round(2).alias('perc')
)

两者都会回来:

shape: (3, 3)
┌────────┬────────┬──────┐
│ person ┆ counts ┆ perc │
│ ---    ┆ ---    ┆ ---  │
│ str    ┆ u32    ┆ f64  │
╞════════╪════════╪══════╡
│ a      ┆ 2      ┆ 40.0 │
│ b      ┆ 2      ┆ 40.0 │
│ null   ┆ 1      ┆ 20.0 │
└────────┴────────┴──────┘

0
投票

.value_counts
.with_columns

df.to_series().value_counts().with_columns(
    (pl.col('count') / df.shape[0]).alias('percent_count')
)

给你正是这样的:

+------+-----+-------------+
|person|count|percent_count|
+------+-----+-------------+
|"a"   |2    |0.666667     |
|"b"   |1    |0.333333     |
+------+-----+-------------+
© www.soinside.com 2019 - 2024. All rights reserved.