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

如何在Python Polars窗口函数中过滤行计算排除式HHI?

在Polars中计算排除当前企业的赫芬达尔-赫希曼指数(HHI)

针对你的大数据集(近800家企业、204个月、500个市场),最高效的实现方式是通过数学公式转换避免窗口内过滤,直接利用Polars的向量化窗口函数完成计算,完全不需要手动处理。

核心思路

排除当前企业的HHI本质是:组内(同一市场+月份)所有其他企业的「规模占排除后总规模的比例」的平方和。

通过数学推导可简化计算:
设:

  • ( S ) = 组内所有企业的总规模
  • ( s_j ) = 当前企业的规模
  • ( \sum s_i^2 ) = 组内所有企业规模的平方和

则排除当前企业后的HHI为:
[
\text{excluded_HHI} = \frac{\sum s_i^2 - s_j^2}{(S - s_j)^2}
]
这个公式将原本O(n²)的计算量压缩到O(n),完美适配大数据集。

Polars代码实现

import polars as pl

# 模拟你的数据集结构(替换为真实数据)
df = pl.DataFrame({
    "market": ["M1"]*3 + ["M2"]*2,
    "month": [202301]*3 + [202301]*2,
    "firm": ["A", "B", "C", "X", "Y"],
    "size": [10, 3, 50, 20, 30]
})

# 计算排除当前企业的HHI
result = df.with_columns(
    # 1. 按市场+月份分组,计算组内总规模、规模平方和
    total_size=pl.col("size").sum().over(["market", "month"]),
    sum_sq=pl.col("size").pow(2).sum().over(["market", "month"])
).with_columns(
    # 2. 用公式计算排除当前企业的HHI
    excluded_hhi=(pl.col("sum_sq") - pl.col("size").pow(2)) / pl.col("total_size").sub(pl.col("size")).pow(2)
).drop("total_size", "sum_sq")  # 可选:删除中间计算列

print(result)

结果验证

以示例中2023年企业A为例:

  • 组内总规模 ( S = 10+3+50=63 )
  • 规模平方和 ( \sum s_i^2 = 10²+3²+50²=2609 )
  • 排除A后的HHI = ( (2609-10²)/(63-10)² = 2509/2809 ≈ 0.893 ),与你给出的( (3/53)²+(50/53)² )结果完全一致。

关于窗口过滤的说明

如果一定要用窗口过滤的方式实现,Polars也支持,但绝对不推荐用于大数据集——这种方式需要对每个企业遍历组内所有其他企业,时间复杂度为O(n²),对于800企业的组会产生指数级的计算量,性能极差。示例代码仅作演示:

# 不推荐:窗口过滤实现(仅适合小数据集)
slow_result = df.with_columns(
    excluded_hhi=pl.col("size")
        .filter(pl.col("firm") != pl.col("firm"))
        .map_elements(lambda s: (s / (pl.col("size").sum().over(["market", "month"]) - pl.col("size")))**2)
        .sum()
        .over(["market", "month"])
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:25