DatetimeIndexによってインデックス付けされたPandasデータフレームがあります:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 53732 entries, 1993-01-07 12:23:58 to 2012-12-02 20:06:23
Data columns:
Date(dd-mm-yy)_Time(hh-mm-ss) 53732 non-null values
Julian_Day 53732 non-null values
AOT_870 53732 non-null values
440-870Angstrom 53732 non-null values
440-675Angstrom 53732 non-null values
500-870Angstrom 53732 non-null values
Last_Processing_Date(dd/mm/yyyy) 53732 non-null values
Solar_Zenith_Angle 53732 non-null values
time 53732 non-null values
dtypes: datetime64[ns](2), float64(6), object(1)
特定の時間に最も近い行を見つけたい:
image_time = dateutil.parser.parse('2009-07-28 13:39:02')
そしてそれがどれだけ近いかを見つけます。これまで、すべての時間から必要な時間を差し引いて、最小の絶対値を見つけるという考えに基づいてさまざまなことを試みましたが、どれもうまくいかないようです。
例えば:
aeronet.index - image_time
日時インデックスの+/-が原因であると思われるエラーが発生するため、インデックスを別の列に配置して、次のように作業しました。
aeronet['time'] = aeronet.index
aeronet.time - image_time
これはうまくいくようですが、私がやりたいことをするためには、相対的な違いではなく、絶対的な時間差を取得する必要があります。ただし、その上でabs
またはnp.abs
を実行すると、エラーが発生します。
abs(aeronet.time - image_time)
C:\Python27\lib\site-packages\pandas\core\series.pyc in __repr__(self)
1061 Yields Bytestring in Py2, Unicode String in py3.
1062 """
-> 1063 return str(self)
1064
1065 def _tidy_repr(self, max_vals=20):
C:\Python27\lib\site-packages\pandas\core\series.pyc in __str__(self)
1021 if py3compat.PY3:
1022 return self.__unicode__()
-> 1023 return self.__bytes__()
1024
1025 def __bytes__(self):
C:\Python27\lib\site-packages\pandas\core\series.pyc in __bytes__(self)
1031 """
1032 encoding = com.get_option("display.encoding")
-> 1033 return self.__unicode__().encode(encoding, 'replace')
1034
1035 def __unicode__(self):
C:\Python27\lib\site-packages\pandas\core\series.pyc in __unicode__(self)
1044 else get_option("display.max_rows"))
1045 if len(self.index) > (max_rows or 1000):
-> 1046 result = self._tidy_repr(min(30, max_rows - 4))
1047 Elif len(self.index) > 0:
1048 result = self._get_repr(print_header=True,
C:\Python27\lib\site-packages\pandas\core\series.pyc in _tidy_repr(self, max_vals)
1069 """
1070 num = max_vals // 2
-> 1071 head = self[:num]._get_repr(print_header=True, length=False,
1072 name=False)
1073 tail = self[-(max_vals - num):]._get_repr(print_header=False,
AttributeError: 'numpy.ndarray' object has no attribute '_get_repr'
私はこれに正しい方法でアプローチしていますか?もしそうなら、どのようにabs
を機能させるべきですか。そうすれば、最小の絶対時間差を選択して、最も近い時間を取得できます。そうでない場合、Pandas時系列でこれを行うための最良の方法は何ですか?
DatetimeIndex.asof
を試して、入力までの最新のラベルを見つけることができると思います。次に、返された日時を使用して適切な行を選択します。特定の列の値のみが必要な場合は、Series.asof
が存在し、上記の2つのステップを1つに結合します。
これは、最も近い日時が必要であることを前提としています。日付を気にせず、毎日同じ時刻が必要な場合は、DataFrameでat_time
を使用します。
編集:誤警報、私はローカルで古いバージョンを持っていました。最新のマスターはnp.absで動作するはずです。
In [10]: np.abs(df.time - image_time)
Out[10]:
0 27 days, 13:39:02
1 26 days, 13:39:02
2 25 days, 13:39:02
3 24 days, 13:39:02
4 23 days, 13:39:02
5 22 days, 13:39:02
また、明確にするために:
aeronet.index-Indexの減算はセットの差であるため、image_timeは機能しません(以前は、Indexは一意になるように制約されていました)。
この単純なメソッドは、指定された日時オブジェクトに最も近いTimeSeriesIndexエントリ(の整数インデックス)を返します。インデックスを通常の列にコピーする必要はありません。代わりに.to_pydatetime
メソッドを使用してください。
import numpy as np
i = np.argmin(np.abs(df.index.to_pydatetime() - image_time))
次に、DataFrameの.iloc
インデクサーを使用するだけです。
df.iloc[i]
これを行う関数は次のとおりです。
def fcl(df, dtObj):
return df.iloc[np.argmin(np.abs(df.index.to_pydatetime() - dtObj))]
その後、さらにシームレスにフィルタリングできます。
fcl(df, dtObj)['column']
私は今日同じ問題に直面していました。指定されたタイムスタンプの前に最も近い値を与えることができる関数が必要でした。これが私が得た関数です:
def get_nearest_past(data, timestamp):
index = data.index.get_loc(timestamp,"ffill")
return data.iloc[index]
グローバルに最も近いものが必要な場合(私の場合のように以前に最も近いものではない)、次を使用できます。
def get_nearest(data, timestamp):
index = data.index.get_loc(timestamp,"nearest")
return data.iloc[index]
詳細については、 get_loc
ドキュメント。