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

如何简化移除DataFrame中值全相同列的代码?可改用for循环或apply吗?

问题描述

假设有如下包含多列值全相同的DataFrame:

df = pd.DataFrame({'State':['Texas','Texas','Texas','Texas'], 'County':['Harris','Harris','Harris','Harris'], 'Building':[1,2,3,4], 'Budget':[7328,3290,8342,4290]})

我想要编写函数扫描该DataFrame并删除值全相同的列,已实现一个可返回被移除列及其唯一值的Series x的drop_monocols函数(代码如下):

def drop_monocols(df):              # 接收DataFrame
    x = dict()
    n = 0
    while n < df.shape[1]:
        if df.iloc[:,n].nunique()==1:                   # 找出所有值相同的列
            x[df.columns[n]] = df.iloc[0,n]             # 将列名和对应唯一值存入字典
            df = df.drop(df.columns[n], axis=1)         # 删除无用列
        else:
            n +=1
    x = pd.Series(x)
    return x, df                                        # 返回无用列的Series和清理后的DataFrame

作为编程新手,我想了解:

  • 是否有更简洁的实现方式?
  • 能否用for循环替代while循环?
  • 是否可以用.apply方法代替传入df的函数?

解答

1. 更简洁的实现方式

利用pandas的向量化操作可以直接筛选目标列,不用逐列循环,效率和可读性都更高:

def drop_monocols(df):
    # 筛选出所有唯一值数量为1的列
    mono_cols = df.columns[df.nunique() == 1]
    # 提取这些列的唯一值(取第一行即可)
    dropped_series = df.loc[0, mono_cols]
    # 删除目标列得到清理后的DataFrame
    cleaned_df = df.drop(mono_cols, axis=1)
    return dropped_series, cleaned_df

df.nunique()会直接返回每一列的唯一值数量,用布尔索引就能一次性筛选出所有单值列,比循环操作高效得多。

2. 用for循环替代while循环

如果偏好for循环,建议先收集所有需要删除的列,再统一处理(避免循环中修改DataFrame列数导致索引混乱):

def drop_monocols(df):
    dropped_dict = {}
    # 遍历所有列,收集单值列及其唯一值
    for col in df.columns:
        if df[col].nunique() == 1:
            dropped_dict[col] = df[col].iloc[0]
    # 统一删除收集到的列
    cleaned_df = df.drop(dropped_dict.keys(), axis=1)
    return pd.Series(dropped_dict), cleaned_df

这种方式逻辑更清晰,不会像原while循环那样因为删除列导致后续索引错位,降低出错概率。

3. 用.apply方法实现

可以用apply给每一列做单值判断,再基于结果处理:

# 定义判断单值列的辅助函数
def is_single_value_col(col):
    return col.nunique() == 1

def drop_monocols(df):
    # 用apply标记每一列是否为单值列
    mono_col_mask = df.apply(is_single_value_col)
    # 筛选出单值列的列名
    mono_cols = mono_col_mask[mono_col_mask].index
    # 提取唯一值并清理DataFrame
    dropped_series = df.loc[0, mono_cols]
    cleaned_df = df.drop(mono_cols, axis=1)
    return dropped_series, cleaned_df

df.apply(is_single_value_col)会对每一列执行判断函数,返回一个布尔Series,后续操作和第一种简洁方式一致,适合需要拆分逻辑的场景。

另外提醒:尽量避免在循环中直接修改原DataFrame的结构(比如原while循环里逐列删除),先收集目标列再统一处理是pandas编程的常规好习惯。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:02:38