在Altair/Vega-lite中如何按分组类别显示占比而非总计占比?
解决方案
要实现每个国家分组自身的薪资占比,你需要调整数据转换的顺序,先对薪资进行分箱,再统计每个分箱在对应分组内的占比。以下是修正后的代码:
import numpy as np import pandas as pd import altair as alt salaries = { 'NL': np.random.normal(loc=80000, scale=30000, size=(500,)), 'ES': np.random.normal(loc=80000, scale=30000, size=(50,)) } source = pd.DataFrame({k:pd.Series(v) for k,v in salaries.items()}) c = alt.Chart(source).transform_fold( ['NL', 'ES'], as_=['Benchmark', 'Salaries'] ).transform_joinaggregate( # 计算每个国家的总样本数 total='count(*)', groupby=['Benchmark'] ).transform_bin( # 显式对薪资分箱,替代encode中的bin设置 'binned_salaries', field='Salaries', maxbins=20 ).transform_aggregate( # 统计每个国家+分箱的样本数量 bin_count='count(*)', groupby=['Benchmark', 'binned_salaries', 'total'] # 保留total字段用于后续计算 ).transform_calculate( # 计算当前分箱在对应国家内的占比 pct='datum.bin_count / datum.total' ).mark_bar(opacity=0.3, binSpacing=0).encode( alt.Color('Benchmark:N'), x=alt.X('binned_salaries:Q', title='Salaries'), y=alt.Y('pct:Q', axis=alt.Axis(format='%'), stack=None) ) c.display()
关键调整说明
- 显式分箱:使用
transform_bin提前对薪资进行分箱,替代原代码中在x轴encode里的bin设置,这样能更清晰地控制分箱逻辑,方便后续按分箱+分组统计。 - 分组统计分箱数量:通过
transform_aggregate统计每个国家(Benchmark)和分箱组合的样本数,同时保留之前计算的国家总样本数。 - 直接计算占比:用分箱数量除以对应国家的总样本数,得到该分箱在分组内的占比,避免原代码中通过
sum(pct)可能带来的逻辑混淆。
原代码的逻辑理论上可以实现目标,但显式的分箱+统计方式更直观,也更容易排查问题,尤其适合新手理解数据转换流程。
内容的提问来源于stack exchange,提问作者user3489010
相关产品推荐
相关产品推荐

