当边缘日期不在数据框中时,日期之间的 Pandas 日期索引 loc 会引发 KeyError

我不明白为什么在日期索引上使用 loc 时出现 KeyError: Timestamp('...') 。

给定 df: dtypes are datetime64[ns], int, int , DATE1 is index

            DATE1    VALUE2  VALUE3
2021-08-20 00:00:00      11     424
2021-08-21 00:00:00      22     424
2021-08-22 00:00:00      33     424
2021-08-23 00:00:00      44     242

我正在尝试像这样在索引上使用 loc :

start_date = date(2021-08-20)
end_date = date(2021-08-23)
df = df.loc[start_date:end_date]

这工作正常。我得到了 4 条记录。 但是当我这样做时:

start_date = date(2021-08-20)
end_date = date(2021-08-24) #end_date is higher than values in dataframe
df = df.loc[start_date:end_date]

我收到 KeyError: KeyError: Timestamp('2021-08-24 00:00:00') 。有人可以指出我如何解决这个问题吗?

stack overflow Pandas date index loc between dates throws KeyError when edge date is not in dataframe
原文答案

答案:

作者头像

使用最大值来限制数据中的最后日期:

from datetime import datetime
x = """DATE1|VALUE2|VALUE3
2021-08-20 00:00:00    |  11    | 424
2021-08-21 00:00:00    |  22   |  424
2021-08-22 00:00:00    |  33   |  424
2021-08-23 00:00:00    |  44  |   242"""

def str_to_date(s):
    return datetime.strptime(s.strip(), "%Y-%m-%d %H:%M:%S")

df = pd.read_csv(StringIO(x), sep='|')
df['DATE1'] = df['DATE1'].apply(lambda s: str_to_date(s))
df = df.set_index('DATE1')

然后:

start_date = datetime.strptime('2021-08-20', "%Y-%m-%d")
end_date = min(datetime.strptime('2021-08-24', "%Y-%m-%d"), max(df.index))

df3 = df.loc[start_date:end_date]

[出去]:

    VALUE2  VALUE3
DATE1       
2021-08-20  11  424
2021-08-21  22  424
2021-08-22  33  424
2021-08-23  44  242

min(datetime.strptime('2021-08-24', "%Y-%m-%d"), max(df.index) 行:

  • max_date = max(df.index) 存储最新日期
  • min(end_date, max_date) 采用最近/较低的日期
作者头像

您使用的是哪个pandas版本?这对我来说可以:

start_date = pd.to_datetime('2021-08-20')
end_date = pd.to_datetime('2121-08-24')
df.loc[start_date:end_date]

输出:

            VALUE2  VALUE3
DATE1                     
2021-08-20      11     424
2021-08-21      22     424
2021-08-22      33     424
2021-08-23      44     242
作者头像

为了使用边界超出索引范围的基于标签的切片,索引必须单调递增或递减。

来自 pandas docs

如果 Series 或 DataFrame 的索引单调递增或递减,则基于标签的切片的边界可能超出索引范围,就像切片索引普通 Python 列表一样。可以使用 is_monotonic_increasing() 和 is_monotonic_decreasing() 属性测试索引的单调性。

另一方面,如果索引不是单调的,那么两个切片边界都必须是索引的唯一成员。

您可以使用 df.sort_index 对索引进行排序,然后越界切片应该可以工作。