带时区感知时间戳的Pandas iloc索引异常问题咨询
Pandas iloc返回时区感知时间戳而非行对象的问题解析
这个问题其实是pandas在处理单列单行且包含时区感知Timestamp时的标量优化行为导致的,我来帮你拆解清楚:
问题复现
先结合你提供的代码补充时区感知的测试案例,更直观展示差异:
import dateutil.parser as parser import pandas as pd # 无时区的时间戳DataFrame a = pd.DataFrame({'A':[parser.parse('2018-05-01T12:00:00')]}) print(type(a.iloc[0])) # 输出 <class 'pandas.core.series.Series'> print(a.iloc[0]['A']) # 正常返回 Timestamp(2018-05-01 12:00:00) # 带时区的时间戳DataFrame b = pd.DataFrame({'A':[parser.parse('2018-05-01T12:00:00+08:00')]}) print(type(b.iloc[0])) # 输出 <class 'pandas._libs.tslibs.timestamps.Timestamp'> # 此时执行 b.iloc[0]['A'] 会抛出 AttributeError: 'Timestamp' object has no attribute '__getitem__'
原因分析
pandas内部有个优化逻辑:当你用iloc[n]选取单行时,如果DataFrame只有一列,且该列的元素是pandas认定的「原生标量类型」,会直接返回该标量值,而非构造一个Series行对象。
时区感知的Timestamp被pandas归为这类可直接返回的标量,而无时区的Timestamp在单列单行场景下,pandas会优先返回Series(核心差异在于时区感知类型的标量优化触发优先级更高)。
解决方案
根据你的需求,有几种可行的处理方式:
强制返回单行DataFrame
使用iloc[[0]](注意嵌套方括号)选取,这样会得到一个单行的DataFrame,后续取列的逻辑就和无时区场景一致了:b.iloc[[0]]['A'] # 返回包含带时区时间戳的Series调整访问顺序,先列后行
先定位列再选取行,绕开单行单列的标量优化逻辑:b['A'].iloc[0] # 直接返回带时区的Timestamp,也是最直接获取值的方式用专门的标量访问方法
如果你的需求就是获取时间戳值,推荐用at或iat,它们是pandas专门为快速访问标量设计的方法,性能更优:b.at[0, 'A'] # 通过标签定位访问 b.iat[0, 0] # 通过位置索引访问
内容的提问来源于stack exchange,提问作者Ymareth
相关产品推荐
相关产品推荐

