我经常需要计算变量的百分比计数。例如下面的数据框
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])
)
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 │
└────────┴───────┴───────────────┘
使用
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 │
└────────┴────────┴──────┘
.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 |
+------+-----+-------------+