我在Stackoverflow的这篇文章中找到了这个例子:
import pandas as pd
earliest = pd.Timestamp('2012-01-01 06:00:00')
latest = pd.Timestamp('2014-12-01 23:00:00')
dr = pd.date_range(start=earliest, end=latest,freq="30min")
df_freq = pd.DataFrame(index=dr, columns=['freq'])
df_freq = df_freq.fillna(0)
# use str datetime as key
df_freq['2012-03-04']
这篇文章发表在大约五年前,所以API熊猫可能已经改变了。即使代码在2022年仍然有效,我也收到了以下警告:
FutureWarning: Indexing a DataFrame with a datetimelike index using a single string
to slice the rows, like `frame[string]`, is deprecated and will be removed in a future
version. Use `frame.loc[string]` instead.
然而,这种按日期时间进行的索引似乎只适用于特定的频率。如果您将频率从"30min"
更改为"D"
(每天(,则相同的片段不起作用:
import pandas as pd
earliest = pd.Timestamp('2012-01-01')
latest = pd.Timestamp('2014-12-01')
dr = pd.date_range(start=earliest, end=latest, freq="D") # if freq is D, it does not work
df_freq = pd.DataFrame(index=dr, columns=['freq'])
df_freq = df_freq.fillna(0)
df_freq['2012-03-04']
在这种情况下,我得到了一条KeyError: '2012-03-04'
错误消息。
解决方法很简单,必须使用df_freq.loc['2012-03-04']
进行索引。然而,我不知道为什么我需要更改访问数据帧的频率。这种行为在其他地方有记录吗?
当前pandas docs
表示:
警告
使用带有getitem的单个字符串索引DataFrame行(例如。frame[dtstring](不赞成从pandas 1.2.0开始使用(给定模糊性,无论是对行进行索引还是选择列(以及将在将来的版本中删除。.loc的等效项(例如。frame.loc[dtstring](。
当您查看版本1.1.5
(即1.2.0
之前的最后一个版本(的文档时,您会发现您的问题已经包含在其中:
警告
但是,如果字符串被视为完全匹配,则中的选择DataFrame的[]将按列而非按行,请参阅索引基础知识。例如dft_minute['2011-12-31 23:59']将引发KeyError由于"2012-12-31 23:59"具有与索引相同的分辨率没有这样名称的列:
为了始终具有明确的选择,无论行是否被视为切片或单个选择,使用.loc.
因此,回到您的具体情况,在使用freq="30min"
的第一个示例中,df_freq['2012-03-04']
是而不是完全匹配。例如:
print(df_freq['2012-03-04'].head())
freq
2012-03-04 00:00:00 0
2012-03-04 00:30:00 0
2012-03-04 01:00:00 0
2012-03-04 01:30:00 0
2012-03-04 02:00:00 0
但是,在使用freq="D"
的第二个示例中,df_freq['2012-03-04']
确实构成了完全匹配。结果,程序开始寻找column
匹配,而不是index
匹配。由于您的df_freq
没有任何这样的列,因此您会收到错误。事实上,应用于第二个示例的df_freq['2012-03-04']
回溯的最后一部分向您展示了以下内容:
Traceback (most recent call last):
File "script.py", line 8, in <module>
df_freq['2012-03-04']
File "..pandascoreframe.py", line 3505, in __getitem__
indexer = self.columns.get_loc(key)
File "..pandascoreindexesbase.py", line 3623, in get_loc
raise KeyError(key) from err
KeyError: '2012-03-04'
注indexer = self.columns.get_loc(key)
。即故障在于df_freq.columns.get_loc('2012-03-04')
。
所以,这个问题实际上与所选频率无关。第二个例子中的df_freq['2012-03']
仍然会给你一个切片(当然,也有同样的警告(。
使用CCD_ 19也可以避免该问题。应用于您的第二个示例:
print(df_freq['2012-03-04':'2012-03-04'])
freq
2012-03-04 0
但是,请注意,这将返回一个df
切片:
print(type(df_freq['2012-03-04':'2012-03-04']))
<class 'pandas.core.frame.DataFrame'>
对比度.loc
:
print(type(df_freq.loc['2012-03-04']))
<class 'pandas.core.series.Series'>