loc用错索引名会直接报KeyError,因其严格按标签索引,要求行索引和列名必须真实存在且类型匹配,否则报错;需先检查df.index和df.columns,避免混淆标签与位置,赋值务必用loc防止链式赋值失效。
![pandas loc怎么用_loc[行名,列名]按标签索引数据的方法](https://img.php.cn/upload/article/000/969/633/177330822281755.png)
loc 用错索引名会直接报 KeyError
用 loc 按标签取数,前提是行和列必须真有那个标签。很多人把 loc 当成“按名字查”,但忘了 DataFrame 的行索引(index)可能根本不是字符串——比如是默认的 RangeIndex(0, 1, 2…),这时写 df.loc['a', 'col1'] 就会报 KeyError: 'a'。
实操建议:
- 先确认行索引类型:
df.index看输出,是RangeIndex还是Index;如果是前者,loc['a']必然失败,得先设索引:df = df.set_index('id') - 列名同理:用
df.columns检查是否存在目标列名,注意大小写和空格('Name '≠'Name') - 想安全地“尝试取值”,别用
loc直接硬查,改用df.query("col == 'x'")或df[df['col'].eq('x')]
loc\[行条件, 列条件\] 中布尔数组不能混用 label 和位置
loc 是纯标签索引,不接受整数位置(除非索引本身是数字且你明确想按标签查数字)。常见错误是写 df.loc[0:2, ['A','B']] —— 如果 index 是 [10, 20, 30],那 0:2 会返回空,因为 0 和 2 根本不在索引里。
实操建议:
- 切片用标签范围:
df.loc[10:30, ['A','B']](闭区间,含 10 和 30) - 要按位置切前三行?别用
loc,换iloc[0:3] - 布尔条件必须作用于标签或列名:
df.loc[df.index.isin([10,30]), 'A']或df.loc[df['A'] > 5, ['B','C']] - 混合使用时尤其小心:
df.loc[df['A'] > 5, 'B']是合法的,但df.loc[0:2, df['A'] > 5]会出错——右边是布尔 Series,左边是位置式切片,类型不匹配
赋值时 loc\[行, 列\] = value 会原地修改,但链式赋值无效
loc 赋值是唯一推荐的、能稳定生效的标签赋值方式。而 df[df.A > 1]['B'] = 999 这种写法大概率静默失败(SettingWithCopyWarning),因为中间可能产生视图而非原 DataFrame。
实操建议:
- 所有带条件的赋值,统一走
loc:df.loc[df['A'] > 1, 'B'] = 999 - 一次改多列:
df.loc[df['A'] > 1, ['B','C']] = [999, 'new'](等号右边必须长度匹配) - 如果右侧是标量(如
0),会广播到所有选中单元格;如果是列表或数组,长度必须等于选中行数 - 注意 dtype 影响:给 int 列赋
None或np.nan会触发自动转为 float,且无法再塞回 int(除非用Int64nullable 类型)
loc 在多级索引(MultiIndex)里必须传元组或切片
当行索引是两层(比如 (country, year)),loc['China'] 会报错,因为 loc 不知道你是想查第一层还是整个元组。
实操建议:
- 查第一层所有值:
df.loc[('China', slice(None)), 'sales'](slice(None)表示该层全选) - 查某一层的多个值:
df.loc[pd.IndexSlice['China', [2020, 2021]], 'sales'] - 更直白写法:
df.xs('China', level='country')(适合单层提取,不带原索引) - 避免用字符串拼接构造元组,比如
df.loc['China', 2020]在 MultiIndex 下会被解释为两个独立参数,报IndexingError
最常被忽略的是索引类型和赋值意图之间的错位:你以为在按名字找,其实 index 是数字;你以为在安全赋值,其实用了链式操作。loc 不难,但它的“标签”二字必须抠到每一处索引定义里。









