Pandas按组计算方差后删除低方差分组报错问题咨询
错误原因
错误出在rows_to_drop = df[group_vars<threshold].index这一行:
group_vars是按country、level、job title三个字段分组计算得到的Series,它的索引是三级MultiIndex,每个索引对应一个独立分组,示例中长度仅为2。- 原df的索引是默认生成的0~5的int64类型单级索引,和
group_vars的索引维度、数据类型完全不匹配。直接用长度为2的布尔序列去索引长度为6的df,pandas底层做索引对齐时无法兼容两种不同的索引类型,因此抛出Buffer dtype mismatch的错误。
是否可以通过重索引group_vars实现?
可以。核心逻辑是把每个分组计算得到的方差,通过分组键映射回原df中属于该分组的每一行,生成和原df长度一致的布尔掩码,再做行过滤即可。
正确实现方式
方式1:使用transform实现(最简便)
transform会将分组计算的结果自动映射回原分组对应的每一行,无需手动处理索引对齐:
import pandas as pd import numpy as np # 构造示例DataFrame d={'month': ['01/01/2020', '01/02/2020', '01/03/2020', '01/01/2020', '01/02/2020', '01/03/2020'], 'country': ['Japan', 'Japan', 'Japan', 'Poland', 'Poland', 'Poland'], 'level':['A01', 'A01', 'A01', 'A00','A00', 'A00'], 'job title':['Insights Manager', 'Insights Manager', 'Insights Manager', 'Sales Director', 'Sales Director', 'Sales Director'], 'number':[0, 0.001, 0, 0, 0, np.nan], 'age':[24, 22, 45, np.nan, 60, 32]} df = pd.DataFrame(d) # 定义方差阈值 threshold = 0.0000000001 # 分组计算number列方差并映射回每一行 df['group_number_var'] = df.groupby(['country', 'level', 'job title'])['number'].transform('var') # 保留方差不低于阈值的分组行,删除辅助列 df = df[df['group_number_var'] >= threshold].drop('group_number_var', axis=1)
方式2:重索引group_vars实现
如果你需要保留单独计算的group_vars变量,可以通过索引映射实现过滤:
# 计算分组方差 group_vars = df.groupby(['country', 'level', 'job title'])['number'].var() # 用原df的分组键匹配group_vars的索引,生成过滤掩码 filter_mask = df.set_index(['country', 'level', 'job title']).index.map(group_vars.ge(threshold)) # 过滤行 df = df[filter_mask]
两种方式执行后,都会删除方差为0的Poland分组对应的所有行,和预期输出一致。
内容的提问来源于stack exchange,提问作者AlSub
相关产品推荐
相关产品推荐

