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

如何提取Pandas MultiIndex中同时含指定property的ID?

问题描述

我有如下结构的数据集:

import pandas as pd

# Create individual pandas DataFrame.
df1 = pd.DataFrame({'Col1': [1, 2, 3, 4], 'Col2': [99, 98, 95, 90]}, index=['A', 'B', 'C', 'D'])
df2 = pd.DataFrame({'Col1': [1, 2], 'Col2': [99, 98]}, index=['A', 'B'])
df3 = pd.DataFrame({'Col1': [3, 4], 'Col2': [95, 90]}, index=['C', 'D'])
df4 = pd.DataFrame({'Col1': [3, 4], 'Col2': [95, 90]}, index=['B', 'C'])

# Combine into one multi-index dataframe
df_dict = dict(obj1=df1, obj2=df2, obj3=df3, obj4=df4)

# Assign multi-index labels
mDF = pd.concat(list(df_dict.values()), keys=list(df_dict.keys()))
mDF.rename_axis(index=["ID", "property"], inplace=True)
print(mDF, '\n')

生成的MultiIndex DataFrame如下:

Col1  Col2
ID   property            
obj1 A            1    99
     B            2    98
     C            3    95
     D            4    90
obj2 A            1    99
     B            2    98
obj3 C            3    95
     D            4    90
obj4 B            3    95
     C            4    90 

我的需求是:计算所有ID中property为A和B的Col1值之和,但仅针对同时包含A和B两个property的ID(即obj1和obj2)。

我尝试用isin和query方法筛选:

idcs_isin = mDF.index.get_level_values('property').isin(['A', 'B'])
idcs_query = mDF.query('property in ["A","B"]')
print(f'isin:\n{mDF.loc[idcs_isin]}\n')
print(f'Query:\n{idcs_query}')

但结果返回了包含任一指定property的ID(比如obj4只包含B也被纳入):

isin:
               Col1  Col2
ID   property            
obj1 A            1    99
     B            2    98
obj2 A            1    99
     B            2    98
obj4 B            3    95

Query:
               Col1  Col2
ID   property            
obj1 A            1    99
     B            2    98
obj2 A            1    99
     B            2    98
obj4 B            3    95

请问如何提取仅同时包含A和B两个property的ID?

解决方案

方法一:分组后检查属性集合

先筛选出目标property的行,再按ID分组,检查每个分组是否同时包含A和B:

# 筛选出property为A或B的行并按ID分组
target_groups = mDF[mDF.index.get_level_values('property').isin(['A', 'B'])].groupby('ID')

# 收集同时包含A和B的ID
valid_ids = [id for id, group in target_groups if {'A', 'B'}.issubset(group.index.get_level_values('property'))]

# 提取符合条件的数据并计算Col1之和
filtered_data = mDF.loc[valid_ids].query('property in ["A", "B"]')
col1_sum = filtered_data.groupby('ID')['Col1'].sum()

print(col1_sum)

输出结果:

ID
obj1    3
obj2    3
Name: Col1, dtype: int64

方法二:简洁的分组判断

通过重置索引后分组,直接判断每个ID的属性集合是否包含A和B:

# 判断每个ID是否同时包含A和B
has_both_properties = mDF.reset_index().groupby('ID')['property'].apply(lambda x: {'A', 'B'}.issubset(x))

# 获取有效ID列表
valid_ids = has_both_properties[has_both_properties].index

# 计算目标Col1之和
col1_sum = mDF.loc[valid_ids].query('property in ["A", "B"]')['Col1'].groupby('ID').sum()

print(col1_sum)

方法说明

两种方法核心都是先筛选出同时具备A和B属性的ID,再基于这些ID提取对应数据计算总和:

  • 利用集合的issubset方法可以直接判断分组内的属性是否包含目标集合,逻辑清晰直观。
  • 避免了直接筛选属性带来的“包含任一即保留”的问题,精准锁定同时满足两个条件的ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:11:10