这是一个非常简单实用的问题.我觉得它必须是一个愚蠢的细节,应该有类似的问题.我无法找到他们.如果有人,我会高兴地删除这个.
我发现的最接近的是: pandas:用loc迭代DataFrame索引
如何仅在索引为日期和时间时基于时间选择pandas数据帧中的行
无论如何,事情是,我有一个datetime索引的熊猫数据帧如下:
In[81]: y
Out[81]:
PETR4 CSNA3 VALE5
2008-01-01 0.0 0.0 0.0
2008-01-02 1.0 1.0 1.0
2008-01-03 7.0 7.0 7.0
In[82]: y.index
Out[82]: DatetimeIndex(['2008-01-01', '2008-01-02', '2008-01-03'], dtype='datetime64[ns]', freq=None)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,我无法使用以下方法之一访问其值:
In[83]: y[datetime.datetime(2008,1,1)]
In[84]: y['2008-1-1']
In[85]: y['1/1/2008']
Run Code Online (Sandbox Code Playgroud)
我收到了KeyError
错误.
更奇怪的是,以下方法可行:
In[86]: y['2008']
Out[86]:
PETR4 CSNA3 VALE5
2008-01-01 0.0 0.0 0.0
2008-01-02 1.0 1.0 1.0
2008-01-03 7.0 7.0 7.0
In[87]: y['2008-1']
Out[87]:
PETR4 CSNA3 VALE5
2008-01-01 0.0 0.0 0.0
2008-01-02 1.0 1.0 1.0
2008-01-03 7.0 7.0 7.0
Run Code Online (Sandbox Code Playgroud)
我对熊猫很新,所以也许我在这里错过了一些东西?
piR*_*red 31
熊猫正在采取什么内在[]
并决定它应该做什么.如果它是列名的子集,它将返回包含这些列的DataFrame.如果它是一系列索引值,它将返回这些行的子集.什么是不处理是采取单个索引值.
两个解决方案
1.将参数转换为pandas解释为范围的东西.
df['2008-01-01':'2008-01-01']
Run Code Online (Sandbox Code Playgroud)
2.使用旨在为您提供此结果的方法. loc[]
df.loc['2008-01-01']
Run Code Online (Sandbox Code Playgroud)
您可以在索引上使用to_pydatetime函数,因此:
y[y.index.to_pydatetime() == datetime.datetime(2008,1,1)]
Run Code Online (Sandbox Code Playgroud)
反转数据框允许索引工作:
这是您的 .csv 数据文件:
Date,PETR4,CSNA3,VALE5
2008-01-01,0.0,0.0,0.0
2008-01-02,1.0,1.0,1.0
2008-01-03,7.0,7.0,7.0
Run Code Online (Sandbox Code Playgroud)
使用以下咒语将其读入 DataFrame:
>>> a = pd.read_csv('your.csv', index_col=0, parse_dates=True, infer_datetime_format=True)
Run Code Online (Sandbox Code Playgroud)
然后,尝试索引一行:
>>> a['2008-01-01']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 1969, in __getitem__
return self._getitem_column(key)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 1976, in _getitem_column
return self._get_item_cache(key)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/generic.py", line 1091, in _get_item_cache
values = self._data.get(item)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/internals.py", line 3211, in get
loc = self.items.get_loc(item)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/index.py", line 1759, in get_loc
return self._engine.get_loc(key)
File "pandas/index.pyx", line 137, in pandas.index.IndexEngine.get_loc (pandas/index.c:3979)
File "pandas/index.pyx", line 157, in pandas.index.IndexEngine.get_loc (pandas/index.c:3843)
File "pandas/hashtable.pyx", line 668, in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:12265)
File "pandas/hashtable.pyx", line 676, in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:12216)
KeyError: '2008-01-01'
Run Code Online (Sandbox Code Playgroud)
您最终会使用 KeyError 进行回溯
但是,如果您将其反转,如下所示:
>>> b = a[::-1]
Run Code Online (Sandbox Code Playgroud)
然后尝试相同的索引,你会得到正确的结果:
>>> b['2008-01-01']
PETR4 CSNA3 VALE5
Date
2008-01-01 0 0 0
Run Code Online (Sandbox Code Playgroud)
我不知道为什么会这样。有可能,它以一种方式与时间序列有关,但与另一种方式无关?应该有更懂行的人来回答。
更新:通过 RTFM,我发现了这个页面:
https://pandas.pydata.org/pandas-docs/stable/timeseries.html
如果您找到标题为“切片与精确匹配”的部分,则有一条警告解释了这种行为。问题似乎是对于 TimeSeries,精确匹配被解释为列名。对于未排序的数据帧,这不会发生。请参阅上述部分中的警告框。我仍然觉得这非常令人困惑,但是你去...
编辑:修改了b的打印输出,原来是错误的。
编辑 1:在 python 文档中更新解释。