2013-04-23 42 views
32

Python datetime nesnelerini kullanarak pandalar veri çerçevesini okuyabiliyorum ve dilimleyebiliyorum, ancak endekste yalnızca mevcut tarihler'u kullanmak zorunda kaldım. Örneğin, bu çalışır:python pandas dataframe tarih koşullarına göre dilimleme

>>> 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 

Ancak df, ben piton KeyError olsun bulunmayan bir başlangıç ​​veya bitiş tarihini kullanmak durumunda.

Soru: Bir tarih aralığı için veri çerçevesi nesnesini nasıl sorgularım; DataFrame'de başlangıç ​​ve bitiş tarihleri ​​olmadığında bile. Pandalar menzile dayalı dilimlemeye izin veriyor mu?

Ben ilk yakın tarihlerini bulabilirsiniz ve sonra dilimlemekte kullanmak pandalar sürüm 0.10.1

cevap

39

Kullanım searchsorted kullanıyorum.

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

Örnek kopyala yapıştırırsam, iyi çalışır. Ama programımdaki başlangıç ​​ve bitiş değişkenleri, daima veri çerçevesinin uzunluğuna göre varsayılan! Neyi yanlış yapıyorum? - http://pastebin.com/raw.php?i=hfpHqF7s –

+0

“DataFrame” inizi artan düzende sıralamanız gerektiği görünüyor. – waitingkuo

+0

Teşekkürler, veriler artan sırada sıralandığında çalıştı. –

23

Kısa cevap: (data.sort()) verilerinizi sıralama ve sonra her şey bekliyoruz şekilde çalışacaktır düşünüyorum.

Evet, DataFrame'de bulunmayan datetimes'leri kullanarak dilimleyebilirsiniz. Örneğin: Gördüğünüz gibi

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 

, hatta datetime nesneleri oluşturmak gerekmez; dizeleri çalışır.

Dizininizdeki tarihler sıralı olmadığından, davranış tuhaftır. Burada benim örnek endeksi ...

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 

karışık ... ve aynı dilim ele alırsak, biz farklı bir sonuç olsun. Aralığın içindeki ilk elemanı döndürür ve aralığın dışındaki ilk elemanda durur.

In [18]: df['20130419':'20130422'] 
Out[18]: 
        0 
2013-04-22 1.120024 
2013-04-20 -0.721101 
2013-04-24 0.379392 

Bu muhtemelen yararlı bir davranış değildir. Tarih aralığını seçmek istiyorsanız, önce tarihe göre sıralamak mantıklı olur mu?

df.sort_index() 
+0

Bunu yapmaya çalıştığımda, bir python istisnası alıyorum: TimeSeriesError: Kısmi dizinleme yalnızca sipariş verilen zaman dizileri için geçerlidir. –

+0

İstisna kendiliğinden açıklayıcıydı - verileri sıralamayı özlemiştim :(- Teşekkürler, yukarıda gördüğünüz gibi metin tabanlı dilimleme beklendiği gibi çalışır.Ama programdaki tarihler zaten süresiz nesneler olduğu için arama işlevini kullandım. –

+2

df ['20130419': '20130422'] istisnai! Kaba verilerle bile çalışıyor (örn.dizinde bulunmayan bir tarihi belirtmek). Teşekkür ederim! – fantabolous

4

Bunu gerçekleştirmek için basit bir maske kullanabilirsiniz: Bu arada

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

, bu yanı hiyerarşik dizin için çalışır. Bu durumda data.index, data.index.levels[0] veya benzeri ile değiştirilir.

+0

Bu yanıtın daha fazla desteğe ihtiyacı var. Bunu haftalardır aradım! –

İlgili konular