4

datetime.datetime辞書の「キー」がオブジェクトである辞書に現在保存している時系列データがあります。次のようなもの:

data[datetime.datetime(2012,5,14,15,28,2)]={'error':error,'flags':flags,'value':value}

私が持っている質問は次のとおりです。指定された時間の前後に最も近い2回を見つけるための最良の方法は何ですか?この関数は、最も近い2つのポイント間を線形補間するループ内で(〜10,000)呼び出されるため、できるだけ高速にする必要があります。


私は現在、すべてのキー(〜50,000)を検索するため、途方もなく長い時間がかかる1つのメソッドが機能しています。

def findTime(time):
    keys=data.keys()
    bdt=10000000000000000000
    adt=10000000000000000000
    minKey=False
    maxKey=False
    for key in keys:
        dt=(time-key).total_seconds()
        if abs(dt)<bdt and dt>0:
            bdt=abs(dt)
            minKey=key
        elif abs(dt)<adt and dt<0:
            adt=abs(dt)
            maxKey=key
    return minKey,maxKey

バイセクトを使用する私の試み:

def findTime(time):
    keys=data.keys()
    l,r = bisect.bisect_left(time,keys), bisect.bisect_right(time,keys)
    return l,r

残念ながら、これによりエラーが発生します。

TypeError: 'datetime.datetime' object does not support indexing

どんな助けでもいただければ幸いです。

4

3 に答える 3

4

関数はbisect、最初の引数として、ソートされた配列(またはリスト、または実際にはインデックス付けできるもの)を取ります。 keysはソートされていない配列であり、2番目の引数として渡します。

これは機能するはずです:

def findTime(time):
    keys = sorted(data.keys())
    return bisect.bisect_left(keys, time), bisect.bisect_right(keys, time)

ただし、毎回再ソートするのではなく、データを変更していない繰り返し検索のために、ソートされたコピーを保持する必要があります。

于 2012-05-14T20:07:02.097 に答える
3

dictに別のキーを使用する方がはるかに優れています。

2つは明らかです。

1)ISO8601の日付形式を文字列として使用できます。これは本質的にYYYY-MM-DDフォーマットです。フォーマットを使用することもできYYYY-MM-DD:HH:MM:SSます。ISO 8601のプロパティは字句の並べ替えであるため、並べ替えられたキーのリストでは、挿入ポイントの上下にある2つの並べ替えられたキーを使用します。

2)日付の浮動小数点表現を使用できます。整数部分は、ミリメートルマークからオフセットされた日であり、浮動小数点は、HH:MM:SSに簡単に変換される日の一部です。Excel、Windows、Unixはこのアプローチを使用しています。

1)の例:

>>> datetime.datetime.fromtimestamp(time.time()).isoformat()
'2012-05-14T13:55:22.142548'  # a hashable, sortable dict key based on time

2)の例:

>>> time.time()               # That is days and fraction of day since 1/1/1970 
1337028447.499273             # THAT is you dict key
>>> datetime.datetime.fromtimestamp(time.time()).timetuple()
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=14, tm_hour=13, tm_min=52, tm_sec=13, tm_wday=0, tm_yday=135, tm_isdst=-1)

いずれの場合も、Pythonはミリ秒単位で50,000要素のデータ構造を管理できます。

必要に応じて、タイムスタンプを日時オブジェクトに変換します。

于 2012-05-14T20:42:10.343 に答える
1

モジュールに基づいてインデックスを作成するbisectことは、掘り下げる価値のあるアイデアのようです。ただし、ドキュメントを見ると、bisect関数が、2番目の引数ではなく、最初の引数としてソートされたリストを取得していることがわかります。

試す:

keys=sorted(data.keys())
bisect.bisect_left(keys,time), bisect.bisect_right(keys,time)

keysまた、関数の外部でオブジェクトを作成することにより、コードの最適化を試みることができますfindTimedata一連の呼び出しによって辞書が変更されていない場合findTimeは、ソートされたリストの作成に対して1回だけ支払うことになります。

于 2012-05-14T20:08:07.447 に答える