2013-04-23 78 views
32

我能夠使用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

回答

39

使用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 
+0

如果我複製粘貼你的例子,它工作正常。但是我的程序中的開始和結束變量始終默認爲數據幀的長度!我究竟做錯了什麼? - http://pastebin.com/raw.php?i=hfpHqF7s – 2013-04-23 22:21:18

+0

似乎你應該按照升序排列你的'DataFrame'。 – waitingkuo 2013-04-24 01:28:28

+0

謝謝,它在數據按升序排序時工作。 – 2013-04-24 06:21:46

23

簡短的回答:您的數據排序(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() 
+0

當我嘗試這樣做時,我得到一個python異常:TimeSeriesError:部分索引只對有序時間序列有效。 – 2013-04-23 22:27:11

+0

這個例外是自我解釋 - 我錯過了排序數據:(:(謝謝你,上面顯示的基於文本的切片按預期工作)但是我使用了searchsorted函數,因爲程序中的日期已經是datetime對象了。 – 2013-04-24 06:25:24

+2

df ['20130419':'20130422']是例外!即使與稀疏數據(例如指定索引中不存在的日期)。謝謝! – fantabolous 2014-06-26 04:10:45

4

您可以使用一個簡單的面膜來實現:

date_mask = (data.index > start) & (data.index < end) 
dates = data.index[date_mask] 
data.ix[dates] 

順便說一句,這個工程的分層索引爲好。在這種情況下,data.index將替換爲data.index.levels[0]或類似的。

+0

這個答案需要更多upvotes。我一直在尋找這個星期! – 2017-11-06 05:53:11