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

多索引层级DataFrame按不同条件筛选列的优化实现方法咨询

多索引层级DataFrame按不同条件筛选列的优化实现方法咨询

嗨,我完全懂你的需求啦——你现在是想把原来分两次筛选再合并的步骤简化,直接一步到位实现多索引列的差异化条件筛选对吧?其实我们可以利用向量化操作或者列级的条件判断来完成,不用再生成两个中间DataFrame啦,下面给你两种更简洁高效的实现方式:

首先先还原你的原始DataFrame构造(补全了pivot_table的values参数,让逻辑更准确):

import pandas as pd
import numpy as np

df = pd.DataFrame(
    data={
        "data_provider": ["prov_1", "prov_1", "prov_2", "prov_2", "prov_3", "prov_3"],
        "indicator": ["ind_a", "ind_a", "ind_a", "ind_b", "ind_b", "ind_b"],
        "unit": ["EUR", "EUR", "EUR", "EUR", "EUR", "EUR"],
        "year": ["2017", "2018","2019", "2017","2018","2019"],
        "country1": [1, 1, 3, 2, 2, 6],
        "country2": [45, 22, 25, 32, 35, 28]
    }
)

df = df.pivot_table(
    index=['data_provider', 'indicator'],
    columns=['year', 'country1'],
    values='country2',
    fill_value=30
)
df.columns.names = ['item', 'year', 'country1']

方法一:向量化掩码法(推荐,高效适合大数据量)

这种方法通过构造布尔掩码矩阵,一次性对所有列应用对应的筛选条件,避免了中间数据的拷贝,处理大规模数据时优势明显:

# 创建与df形状一致的布尔掩码
mask = np.zeros(df.shape, dtype=bool)

# 对2017年的列:保留值>30的行
year_2017 = df.columns.get_level_values('year') == '2017'
mask[:, year_2017] = df.loc[:, year_2017] > 30

# 对2018年的列:保留值<30的行
year_2018 = df.columns.get_level_values('year') == '2018'
mask[:, year_2018] = df.loc[:, year_2018] < 30

# 对2019年的列:全部设为NaN(即掩码全为False)
year_2019 = df.columns.get_level_values('year') == '2019'
mask[:, year_2019] = False

# 应用掩码得到最终结果
newdf = df.where(mask)

方法二:列级lambda判断法(直观易读,适合小数据量)

如果数据量不大,也可以直接对每一列应用条件判断,代码逻辑更直观,便于理解和修改:

newdf = df.apply(
    lambda col: 
        col.where(col > 30) if col.name[1] == '2017'  # 2017年列:值>30保留,否则设为NaN
        else col.where(col < 30) if col.name[1] == '2018'  # 2018年列:值<30保留,否则设为NaN
        else pd.Series([np.nan]*len(col), index=col.index),  # 2019年列:全部设为NaN
    axis=0
)

这两种方法都不需要像原来那样生成两个中间DataFrame,直接一步就能得到你想要的结果,而且逻辑更集中,后续维护修改条件也更方便。运行后得到的newdf和你期望的目标DataFrame完全一致哦。

备注:内容来源于stack exchange,提问作者missmango

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:54:38