为什么熊猫在查找日期索引表中的日期时会生成 KeyError?

2024-04-25 17:30:49 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑以下代码:

date_index = np.array(['2019-01-01', '2019-01-02'], dtype=np.datetime64)
df = pd.DataFrame({'a': np.array([1, 2])}, index=date_index)
date_to_lookup = date_index[0]
print(df.at[date_to_lookup, 'a'])

人们可能希望它能工作并打印1。然而(至少在anacondapython3.7.3和Pandas0.24.2)中,它失败了,并出现以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../site-packages/pandas/core/indexing.py", line 2270, in __getitem__
    return self.obj._get_value(*key, takeable=self._takeable)
  File ".../site-packages/pandas/core/frame.py", line 2771, in _get_value
    return engine.get_value(series._values, index)
  File "pandas/_libs/index.pyx", line 81, in pandas._libs.index.IndexEngine.get_value
  File "pandas/_libs/index.pyx", line 89, in pandas._libs.index.IndexEngine.get_value
  File "pandas/_libs/index.pyx", line 447, in pandas._libs.index.DatetimeEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 987, in pandas._libs.hashtable.Int64HashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 993, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 17897

Pandas DataFrame和Series对象总是将日期存储为数据类型'datetime64[ns]''datetime64[ns, tz]',这是因为Pandas在创建索引时会自动将'datetime64[D]'数据类型转换为'datetime64[ns]',但在该索引中查找元素时不会这样做。我可以通过将键转换为'datetime64[ns]'来避免上述错误。例如,以下两行都成功打印1

print(df.at[pd.to_datetime(date_to_lookup), 'a'])
print(df.at[date_to_lookup.astype('datetime64[ns]'), 'a'])

这种行为(在创建索引时自动进行数据类型转换,但在查找元素时不自动进行数据类型转换)似乎违反了我的直觉。为什么要这样实施?有没有什么编码风格可以避免这样的错误?或者这是一个我应该归档的bug?你知道吗


Tags: toinpandasdfgetdateindexvalue
2条回答

我认为这是您在0.24.2中发现的一个bug,它在我的系统python 3.7.2和pandas 0.25.3上工作:

date_index = np.array(['2019-01-01', '2019-01-02'], dtype=np.datetime64) 
df = pd.DataFrame({'a': np.array([1, 2])}, index=date_index) 
date_to_lookup = date_index[0] 
print(df.at[date_to_lookup, 'a'])                                                                                                                                                                
1

您可以通过使用^{}^{}选择列a的位置来避免这种情况:

print(df.iat[0, df.columns.get_loc('a')])
#alternative
#print(df.iloc[0, df.columns.get_loc('a')])
1

另一个想法是使用df.index来选择date_index[0]

print(df.at[df.index[0], 'a'])

相关问题 更多 >