2013-04-23 20 views
32

私は、Python datetimeオブジェクトを使用してpandasデータフレームを読み取り、スライスすることができますが、インデックスにはの既存の日付しか使用しないでください。たとえば、この作品:私はDFに存在しない開始日または終了日を使用している場合python pandasデータフレームのスライス日付条件

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

はしかし、私のpython 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 –

+0

'DataFrame'を昇順にソートする必要があります。 – waitingkuo

+0

データが昇順でソートされていればうまくいきました。 –

23

短い答え:(data.sort())あなたのデータをソートしてから、私はすべてがあなたが期待しているように動作すると思います。

はい、DataFrameに存在しないdatetimesを使用してスライスできます。例:

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オブジェクトを作成する必要はありません。弦は機能する。

インデックスのdatetimesが連続していないため、動作が異常です。私たちはここに...

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:部分的なインデックス付けは、順序付けられた時系列に対してのみ有効です。 –

+0

例外は自明です - 私はデータをソートしていませんでした:( - ありがとう、上記のテキストベースのスライスは期待どおりに機能しますが、プログラム内の日付はすでにdatetimeオブジェクトだったのでsearchsorted関数を使用しました) –

+2

df ['20130419': '20130422']は例外的です!疎なデータでも動作します(例:索引に存在しない日付を指定します)。ありがとうございました! – fantabolous

4

あなたはこれを達成するために、単純なマスクを使用することができます:ところで

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

が、これも同様に、階層インデックスのために動作します。その場合、data.indexdata.index.levels[0]または同等に置き換えられます。

+0

この回答はより多くのupvotesが必要です。私は数週間これを探してきました! –

関連する問題