python熊猫数据帧按日期条件切片
我能够使用python datetime对象读取和分割熊猫数据框,但是我只能在索引中使用现有日期。例如,这个工程:python熊猫数据帧按日期条件切片
>>> data
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 252 entries, 2010-12-31 00:00:00 to 2010-04-01 00:00:00
Data columns:
Adj Close 252 non-null values
dtypes: float64(1)
>>> st = datetime.datetime(2010, 12, 31, 0, 0)
>>> en = datetime.datetime(2010, 12, 28, 0, 0)
>>> data[st:en]
Adj Close
Date
2010-12-31 593.97
2010-12-30 598.86
2010-12-29 601.00
2010-12-28 598.92
但是,如果我使用的DF,我得到蟒蛇KeyError异常是不存在的开始或结束日期。
我的问题:如何查询数据框对象的日期范围;即使DataFrame中不存在开始日期和结束日期也是如此。熊猫是否允许基于范围的切片?
我使用熊猫版本0.10.1
使用searchsorted
先找到最近的次,然后用它来切。
In [15]: df = pd.DataFrame([1, 2, 3], index=[dt.datetime(2013, 1, 1), dt.datetime(2013, 1, 3), dt.datetime(2013, 1, 5)])
In [16]: df
Out[16]:
0
2013-01-01 1
2013-01-03 2
2013-01-05 3
In [22]: start = df.index.searchsorted(dt.datetime(2013, 1, 2))
In [23]: end = df.index.searchsorted(dt.datetime(2013, 1, 4))
In [24]: df.ix[start:end]
Out[24]:
0
2013-01-03 2
简短的回答:您的数据排序(data.sort()
),然后我想一切都会工作,你期待的方式。
是的,您可以使用不存在于DataFrame中的日期时间进行切片。例如:
In [12]: df
Out[12]:
0
2013-04-20 1.120024
2013-04-21 -0.721101
2013-04-22 0.379392
2013-04-23 0.924535
2013-04-24 0.531902
2013-04-25 -0.957936
In [13]: df['20130419':'20130422']
Out[13]:
0
2013-04-20 1.120024
2013-04-21 -0.721101
2013-04-22 0.379392
正如你所看到的,你甚至不必建立datetime对象;字符串工作。
因为索引中的日期时间不是顺序的,所以行为很奇怪。如果我们在这里洗牌我的例子指数...
In [17]: df
Out[17]:
0
2013-04-22 1.120024
2013-04-20 -0.721101
2013-04-24 0.379392
2013-04-23 0.924535
2013-04-21 0.531902
2013-04-25 -0.957936
...并采取相同的切片,我们得到了不同的结果。它返回范围内的第一个元素,并停止在范围外的第一个元素。
In [18]: df['20130419':'20130422']
Out[18]:
0
2013-04-22 1.120024
2013-04-20 -0.721101
2013-04-24 0.379392
这可能不是有用的行为。如果你想选择日期范围,首先按日期排序是否合理?
df.sort_index()
当我尝试这样做时,我得到一个python异常:TimeSeriesError:部分索引只对有序时间序列有效。 – 2013-04-23 22:27:11
这个例外是自我解释 - 我错过了排序数据:(:(谢谢你,上面显示的基于文本的切片按预期工作)但是我使用了searchsorted函数,因为程序中的日期已经是datetime对象了。 – 2013-04-24 06:25:24
df ['20130419':'20130422']是例外!即使与稀疏数据(例如指定索引中不存在的日期)。谢谢! – fantabolous 2014-06-26 04:10:45
您可以使用一个简单的面膜来实现:
date_mask = (data.index > start) & (data.index < end)
dates = data.index[date_mask]
data.ix[dates]
顺便说一句,这个工程的分层索引为好。在这种情况下,data.index
将替换为data.index.levels[0]
或类似的。
这个答案需要更多upvotes。我一直在寻找这个星期! – 2017-11-06 05:53:11
如果我复制粘贴你的例子,它工作正常。但是我的程序中的开始和结束变量始终默认为数据帧的长度!我究竟做错了什么? - http://pastebin.com/raw.php?i=hfpHqF7s – 2013-04-23 22:21:18
似乎你应该按照升序排列你的'DataFrame'。 – waitingkuo 2013-04-24 01:28:28
谢谢,它在数据按升序排序时工作。 – 2013-04-24 06:21:46