Python 如何通过名称或编号检查数据框中是否存在列

Python How to check presence of a column in dataframe by it's name or number

我编写了一个函数,它要求用户输入列名(例如 'Age')或列号(0、1、...或 -1、-2、...)和 returns 如果存在的话。我想知道我的解决方案是否可以在代码设计方面得到改进。

为了澄清,我需要这段代码用于另一个函数,该函数在应手动选择标签列的数据帧上计算香农熵。

import pandas as pd

df = pd.DataFrame({'A': [1,2,3], 'B':['a', 'b', 'c']})

def read(df):
    while True:
        column = input("Please, enter column name or number:") 
        if column.lstrip('-').isdecimal():
            if (-df.shape[1] > int(column)) or (int(column) >= df.shape[1]):
                print('Such column does not exist. Please, try again. \n')
                continue
            else:
                return df.iloc[:, int(column)]
        elif column not in df.columns:
            print('Such column does not exist. Please, try again. \n')
            continue
        else:
            return df.loc[:, column]
    return data[column]

read(df)

这些列在 df.columns 中可用,可用于获取您想要的数据。如果该列不在 df.columns 中,请尝试将其转换为 int 以索引 df.columns 并使用异常处理程序来处理未命中。

import pandas as pd

df = pd.DataFrame({'A': [1,2,3], 'B':['a', 'b', 'c']})

def read(df):
    while True:
        column = input("Please, enter column name or number:")
        if column not in df.columns:
            try:
                column = df.columns[int(column)]
            except (IndexError, ValueError):
                print(f"Column {column!r} does not exist, Please try again.")
                continue
        break
    return df.loc[:, column]

print(read(df))

EAFP 方法会说我们应该尝试从 DataFrame select 并处理出现的错误,因为 pandas 已经做了很多工作来查看是否索引器是否有效:

如果我们完全朝着这个方向前进,我们最终会得到类似的结果:

def read(df_: pd.DataFrame) -> pd.Series:
    while True:
        column = input("Please, enter column name or number:")
        try:
            # Attempt to return the Column
            return df_[column]
        except KeyError:
            try:
                # Attempt to convert the column to int and return the column
                return df_.iloc[:, int(column)]
            except (ValueError, IndexError):
                # Print Message if both attempts fail
                print('Such column does not exist. Please, try again. \n')

我已将函数参数从 df 更改为 df_ 以避免从外部范围隐藏变量。

我们首先读取列,然后尝试return 子集DataFrame。如果 DataFrame 中不存在,则会引发 KeyError。在这种情况下,我们尝试按位置访问这些值。 int(column) 如果无法转换为 int 将引发 ValueError,如果索引器超出范围,iloc 将产生 IndexError


对此稍作修改的版本是:

def read(df_: pd.DataFrame) -> pd.Series:
    while True:
        try:
            column = input("Please, enter column name or number:")
            try:
                # Try to get int indexer from df_.columns
                indexer = df_.columns.get_loc(column)
            except KeyError:
                # Use int version of Column
                indexer = int(column)
            return df_.iloc[:, indexer]
        except (ValueError, IndexError):
            # Catch Invalid int conversion, or out of bounds indexes
            print('Such column does not exist. Please, try again. \n')

这里我们使用 Index.get_loc,它“获取所请求标签的整数位置、切片或布尔掩码。”如果标签不在列中,这也会引发 KeyError,但是,在这种情况下,我们尝试在 except.[=34= 中将 column 转换为 indexer ]

这意味着 indexer 保证是基于整数位置的,并且可以传递给 iloc。然后我们可以排除int转换失败导致的ValueError,以及索引器越界时发生的IndexError