You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多索引分类变量的频率高效计算方法探究

高效计算多索引DataFrame中按i分组的分类变量频率

你的原方案在小规模数据下可用,但面对百万级数据时,apply逐行执行value_counts的方式会成为性能瓶颈。这里有两个更Python化且高效的实现方式:

方法1:groupby + value_counts 一键搞定

直接按i分组,借助value_counts的normalize=True参数自动计算频率,再通过unstack将分类变量转为列,缺失值用0填充:

import pandas as pd
import numpy as np

# 生成测试数据
I = range(10)
J = range(3)
K = range(2)

data = pd.DataFrame(
    np.random.randint(0, 3, size=len(I)*len(J)*len(K)),
    index=pd.MultiIndex.from_product([I, J, K]),
    columns=['cat']
)
data.index.names = ['i', 'j', 'k']
# 用map替换多次布尔索引,更简洁高效
data['cat'] = data['cat'].map({0: 'A', 1: 'B', 2: 'C'})

# 核心计算逻辑
result = data.groupby('i')['cat'].value_counts(normalize=True).unstack(fill_value=0)

方法2:crosstab 直观交叉表实现

如果偏好交叉表的思路,pd.crosstab配合normalize='index'也能快速得到结果:

result = pd.crosstab(
    index=data.index.get_level_values('i'),
    columns=data['cat'],
    normalize='index'
).fillna(0)

性能优化核心点

  • 原方案的unstack+apply是Python层面的逐行循环,效率极低;上述两种方法都是pandas底层的向量化操作,利用C扩展加速,百万级数据下差距显著。
  • 用map替换多次布尔索引赋值,减少了不必要的DataFrame切片操作,代码更简洁。
  • normalize参数直接完成频率计算,无需手动除以len(J)*len(K),避免冗余代码和潜在计算错误。

内容的提问来源于stack exchange,提问作者clueless

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 09:57:41