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

pandas统计子组间元素共现频次的实现、优化与报错解决

Pandas 跨分组异源Name共现统计实现问题

初始问题描述

我有如下一个多层索引(multi-index)Series:

(multi-index)              |  Count  |
Group  |  Source  |  Name  |
______________________________________
  A    |    X     |  Jolly |   2
       |          |  Stone |   1
       |    Y     |  Sand  |   1
  B    |    X     |  Sand  |   1
       |    Y     |  Beach |   1

我同时持有生成上述Series的原始DataFrame,结构如下:

Group  |  Source  |  Name
___________________________
  A    |    X     |  Jolly
  A    |    X     |  Stone
  A    |    X     |  Jolly
  A    |    Y     |  Sand
  B    |    X     |  Sand
  B    |    X     |  Beach
  B    |    Y     |  Stone

数据满足如下规则:

  • 每个Group下一定同时存在Source为X和Y的条目
  • 同一Group内X、Y对应的Name无重叠:即同一Group下,若某个Name出现在Source=X的条目中,就不会出现在Source=Y的条目中

我的需求是统计同一Group内、不同Source下的Name两两共同出现的次数:例如在Group A中,Source=X下Jolly出现2次、Stone出现1次,对应Source=Y下的Name为Sand;如果跨Group观察到来自不同Source的两个Name频繁共现,即可推断二者指向同一实体。需要基于pandas实现该统计,暂无固定预期输出格式,类似如下交叉统计矩阵即可:

Y
            Stone | Sand  |  Beach  |  Water
   Stone      NaN     1       NaN       NaN
X  Sand       1      NaN      NaN       NaN
   ...      ...      ...      ...       ...

EDIT #1:现有实现性能不足

我基于已有回答写出了如下实现代码:

def get_source_grouped_combos(df):
    src_x = df[df['Source'] == 'X'].groupby('Name').count()
    src_y = df[df['Source'] == 'Y'].groupby('Name').count()
    return list(product(src_x.index.values, src_y.index.values))

((dfex.loc[dfex['Group'].map(
    dfex.groupby(['Group','Source'])['Name']
    .agg(set)
    .groupby(level=0)
    .agg(lambda x: len(set.intersection(*x))==0))])
 .groupby(['Group'])[['Source','Name']]
 .apply(get_source_grouped_combos)
 .explode('Name')
 .agg(set)
 .value_counts()
)

代码在示例数据上运行后得到如下输出:

{Sand, Stone}     2
{Jolly, Sand}     1
{Beach, Stone}    1
dtype: int64

但该实现使用apply方法运行速度较慢,需要性能更优的实现方案。


EDIT #2:实际数据集运行报错

我将上述代码应用到实际数据集(各列数据类型dtype与示例完全一致)时,代码最后两行:

.agg(set)
 .value_counts()

抛出如下错误:

AttributeError: 'set' object has no attribute 'value_counts'

排查发现.agg(set)会将整个Series包装为一个集合,而非对Series中的每个值逐元素执行集合转换,需要修复该问题,以实现对每个Name集合的出现频次统计。


EDIT #3:NaN值引发异常的原因疑问

我进一步排查发现该问题由数据中存在NaN值引发,想了解为何当Series中存在NaN值时,.agg(set)会将整个Series转为单个集合,而非对每个元素逐元素执行转换?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:30:50