Skip to main content
 首页 » 编程设计

python之在 pandas DataFrame 中删除列级别的方法链接解决方案

2025年05月04日25bjzhanghao

在 reshape 和查询我在 pandas DataFrames 中的数据时,我使用了很多方法链接。有时会为索引(行)和列创建额外的和不必要的级别。如果是这样,例如在索引(行轴)上,这很容易通过使用 DataFrame.reset_index() 解决:

df.query('some query') 
   .apply(cool_func) 
   .reset_index('unwanted_index_level',drop=True) # <==== 
   .apply(another_cool_func) 

reset_index 函数允许继续链式方法并继续使用 DataFrame。

然而,我从未找到 column_axis 的等效解决方案。到底有没有?

请您参考如下方法:

您可以堆叠列(将其移动到索引)并使用drop=True调用reset_index,或者您可以编写一个reset_columns() 方法使用 reset_index() 作为起点(参见 frame.py#L2940)

df.query('some query') 
   .apply(cool_func) 
   .stack(level='unwanted_col_level_name') 
   .reset_index('unwanted_col_level_name',drop=True) 
   .apply(another_cool_func) 

备选方案:猴子补丁解决方案

def drop_column_levels(self, level=None, inplace=False): 
        """ 
        For DataFrame with multi-level columns, drops one or more levels. 
        For a standard index, or if dropping all levels of the MultiIndex, will revert 
        back to using a classic RangeIndexer for column names. 
 
        Parameters 
        ---------- 
        level : int, str, tuple, or list, default None 
            Only remove the given levels from the index. Removes all levels by 
            default 
        inplace : boolean, default False 
            Modify the DataFrame in place (do not create a new object) 
 
        Returns 
        ------- 
        resetted : DataFrame 
        """ 
        if inplace: 
            new_obj = self 
        else: 
            new_obj = self.copy() 
 
        new_columns = pd.core.common._default_index(len(new_obj.columns)) 
        if isinstance(self.index, pd.MultiIndex): 
            if level is not None: 
                if not isinstance(level, (tuple, list)): 
                    level = [level] 
                level = [self.index._get_level_number(lev) for lev in level] 
                if len(level) < len(self.columns.levels): 
                    new_columns = self.columns.droplevel(level) 
 
        new_obj.columns = new_columns 
        if not inplace: 
            return new_obj 
 
# Monkey patch the DataFrame class 
pd.DataFrame.drop_column_levels = drop_column_levels