多索引DataFrame不同维度布尔过滤报错求助
多索引DataFrame同时按行索引与列维度过滤的问题解决
问题场景
需要对多索引的DataFrame,同时基于行索引employ_start_date和列维度employ_class进行过滤。
数据构造代码
import pandas as pd data = pd.DataFrame({'agcy_nbr': {0: 166, 1: 435, 2: 129, 3: 129, 4: 129}, 'employ_class': {0: 'Corr', 1: 'LE', 2: 'Corr', 3: 'Corr', 4: 'Corr'}, 'employ_start_date': {0: 1999, 1: 2001, 2: 2002, 3: 204, 4: 1995}, 'person_nbr': {0: 156723, 1: 154633, 2: 109360, 3: 139837, 4: 153842}}) df = pd.pivot_table(data, index = ['agcy_nbr', 'employ_start_date'], columns = ['employ_class'], values = ['person_nbr'], aggfunc = 'count')
单独过滤的正常操作
- 按列维度
employ_class过滤:
df.iloc[:,df.columns.get_level_values('employ_class') == 'LE']
- 按行索引
employ_start_date过滤:
df[df.index.get_level_values('employ_start_date') > 2000]
组合过滤的报错情况
尝试同时应用两个条件时,执行以下代码出现错误:
df.iloc[:,(df.index.get_level_values('employ_start_date') > 2000) & (df.columns.get_level_values('employ_class') == 'LE')]
错误信息:
ValueError: operands could not be broadcast together with shapes(5,) (2,)
报错原因
行过滤条件返回的是5个元素的布尔数组(对应DataFrame的5行数据),列过滤条件返回的是2个元素的布尔数组(对应DataFrame的2列数据),两者形状不兼容,无法直接进行逻辑运算。而且iloc的列位置参数只接受列维度的布尔数组,不能混入行维度的过滤条件。
解决方法
不需要用iloc同时处理行和列过滤,分开执行两次筛选即可,以下两种方式任选:
方式一:先筛行再筛列
先按行索引筛选出符合条件的行,再对结果按列维度筛选:
filtered_df = df[df.index.get_level_values('employ_start_date') > 2000].iloc[:, df.columns.get_level_values('employ_class') == 'LE']
方式二:用loc直接指定行列条件
利用loc支持多索引的特性,直接同时指定行和列的过滤条件,代码更简洁:
# 直接指定列的层级索引 filtered_df = df.loc[df.index.get_level_values('employ_start_date') > 2000, ('person_nbr', 'LE')] # 若要保留原列结构,也可以用布尔数组筛选列 filtered_df = df.loc[df.index.get_level_values('employ_start_date') > 2000, df.columns.get_level_values('employ_class') == 'LE']
结果验证
执行上述代码后,会得到同时满足两个条件的结果:仅保留employ_start_date>2000的行,且仅保留employ_class='LE'的列。
内容的提问来源于stack exchange,提问作者Arthur Langlois
相关产品推荐
相关产品推荐

