pandas方括号[]索引器用法易混淆 是否应优先使用loc/iloc
pandas方括号索引器使用疑问
现象复现
pandas的[]索引器行为确实存在歧义,可通过以下代码复现所有问题:
import pandas as pd import numpy as np aa = np.asarray([[1,2,3],[4,5,6],[7,8,9]]) df = pd.DataFrame(aa) df
初始化后的DataFrame内容:
0 1 2 0 1 2 3 1 4 5 6 2 7 8 9
- 传入单个标量做索引时,
[]默认匹配列名,df[1]会返回列名为1的整列数据:
0 2 1 5 2 8 Name: 1, dtype: int32
- 传入切片对象时,
[]默认按行位置做筛选,df[1:3]会返回位置索引1到2的行(切片规则遵循Python左闭右开逻辑):
0 1 2 1 4 5 6 2 7 8 9
- 传入二维坐标时,
[]会把传入的元组整体当成单个列名去匹配,df[1,2]会因为找不到名为(1,2)的列直接抛出KeyError,完全不支持同时指定行列定位。报错栈如下:
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Untitled-1.ipynb Cell 19' in <cell line: 1>() ----> 1 df[1,2] File d:\ProgramData\Miniconda3\lib\site-packages\pandas\core\frame.py:3458, in DataFrame.__getitem__(self, key) 3456 if self.columns.nlevels > 1: 3457 return self._getitem_multilevel(key) -> 3458 indexer = self.columns.get_loc(key) 3459 if is_integer(indexer): 3460 indexer = [indexer] File d:\ProgramData\Miniconda3\lib\site-packages\pandas\core\indexes\range.py:388, in RangeIndex.get_loc(self, key, method, tolerance) 386 except ValueError as err: 387 raise KeyError(key) from err --> 388 raise KeyError(key) 389 return super().get_loc(key, method=method, tolerance=tolerance) KeyError: (1, 2)
使用建议
生产环境写可复用代码时,必须优先用loc/iloc做索引,完全可以避免[]带来的歧义问题:
loc是显式按标签(行名、列名)索引,iloc是显式按整数位置索引,行为完全可预测,读代码的人不需要猜测当前操作是选行还是选列。[]的隐式判断逻辑存在大量边缘坑:比如当列名刚好是切片类型、布尔值,或者列名和行索引存在值重叠时,[]的返回结果很可能和你的预期不符,这类隐式bug排查成本极高。- 唯一可以随意用
[]的场景是做交互式数据探索:写df['目标列名']选单列比df.loc[:, '目标列名']简洁很多,临时写分析代码时用完全没问题,只要别把这种写法带到需要长期维护的代码里就行。
额外提醒:比
[]更不推荐的是属性索引写法df.列名,遇到列名带空格/特殊字符、列名和DataFrame内置方法/属性重名时会直接失效,可靠性比[]还差。
内容的提问来源于stack exchange,提问作者ROSS XIE
相关产品推荐
相关产品推荐

