df['col']是安全、通用、推荐的列访问方式;df.col是有严格限制的属性访问机制,仅当列名符合Python标识符规则且不与内置属性冲突时才生效,否则静默失败或报错。
df['col'] 和 df.col 看似一样,其实根本不是一回事
直接说结论:
是安全、通用、推荐的列访问方式;
是有严格限制的“快捷写法”,不是语法糖,而是属性访问机制,用错会静默失败或报错。
为什么 df.col 会突然不工作?常见错误现象
你写了
却得到
—— 这不是 bug,是预期行为。因为:
实际上是在尝试访问 DataFrame 的 Python 属性(类似调用
或
),它只在列名满足 Python 标识符规则时才“碰巧”生效
列名含空格(如
)、数字开头(如
)、特殊符号(如
)或与内置方法同名(如
、
、
)时,
必然失效
即使列名合法(如
),若 DataFrame 已存在同名方法(比如你手动加了
),也会被覆盖或冲突
df['col'] 能干啥,df.col 不能干?实操建议
是 Pandas 显式索引协议的一部分,稳定、可预测、无歧义;
只是它的“弱替代”,且不可逆向操作:
✅ 合法:支持创建/赋值新列
❌ 不合法:Pandas 会发出
,且赋值无效(数据不会写入 DataFrame)
✅ 合法:返回 DataFrame;而
❌ 语法错误,无法链式取多列
列名是变量时,只能用
(
),
完全无法动态解析
性能和兼容性:别为省两个字符冒险
有人觉得
“更快”——实际测试中差异可忽略(纳秒级),但代价是:
代码脆弱:列名一改,所有
处都得重查、重改,IDE 也无法可靠跳转或补全
协作风险:队友可能误以为这是“标准写法”,后续加列名含空格的 CSV 就直接崩
Pandas 官方文档明确标注:属性访问仅用于“便捷读取已知合法列名”,不用于生产逻辑
真正容易被忽略的是:当你用
读取一列,得到的是
;但如果你误以为它和
完全等价,后续做
或布尔索引时,可能因索引对齐问题引入隐式错误——因为属性访问绕过了 Pandas 的索引一致性检查机制。
df['col']df.coldf.nameAttributeError: 'DataFrame' object has no attribute 'name'df.coldf.shapedf.index'user id''3rd_visit''price($)' 'items''T''dt'df.col'age'df.age = ...df['col']df.coldf['new_col'] = [...] df.new_col = [...] UserWarningdf[['col1', 'col2']] df.col1.col2df[col_name]col_name = 'sales_q1'df.col_namedf.coldf.coldf.colpd.Seriesdf['col'].loc