タイムセグメントを作成する日時のリストがあります。つまり、_[t0, t1, ... tn]
_を[(t0,t1),(t1,t2),...,(tn-1, tn)]
に変換します。私はそれをこのようにしました:
_# start by sorting list of datetimes
mdtimes.sort()
# construct tuples which represent possible start and end dates
# left edges
dtg0 = [x for x in mdtimes]
dtg0.pop()
# right edges
dtg1 = [x for x in mdtimes]
dtg1.reverse()
dtg1.pop()
dtg1.sort()
dtsegs = Zip(dtg0,dtg1)
_
質問...
mdtimes
リストをリスト内包表記でコピーするのは良い習慣ですか?そうでない場合、それはどのように行われるべきですか?これらのタプルを作成する目的は、タプルを反復処理し、データセットを_tn-1
_およびtn
でセグメント化することです。これは合理的なアプローチですか?つまり.
_datasegment = [x for x in bigdata if ( (x['datetime'] > tleft) and (x['datetime'] < tright))]
_
ありがとう
タプルの順序は、タプルに値を挿入するときです。あなたが求めていると思うように、それらはソートされません。 Zip
は、値を挿入した順序を保持します。
これは許容できる方法ですが、2つの代替案があります。 copy モジュールを使用するか、dtg1 = mdtimes[:]
を使用します。
合理的に聞こえます。
list
とTuple
の両方が順序付けられています。
dtg0, dtg1 = itertools.tee(mdtimes)
next(dtg0)
dtsegs = Zip(dtg0, dtg1)
Zip
でも同じことができます。
>>> l = ["t0", "t1", "t2", "t3", "t4", "t5", "t6"]
>>> Zip(l[::2], l[1::2])
[('t0', 't1'), ('t2', 't3'), ('t4', 't5')]
代わりに:_dtg0 = [x for x in mdtimes]
_、_dtg0 = mdtimes[:]
_は、あるリストを別のリストにコピーするだけなので、そうします。注:Python 3.3から、newlist = oldlist.copy()
とだけ言うことができます
順序に関しては、Zip
の順序が明確に定義されており、リストとタプルの両方が順序付けられたコレクションであるため、ここでは問題はありません。
(x1、x2、x3、...)を[(x1、x2)、(x2、x3)、...]に変換することはペアワイズの組み合わせと呼ばれ、非常に一般的なパターンであるため、 itertools ドキュメントはレシピを提供します:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
for ta, tb in pairwise(mdtimes):
....
これは「これは合理的なアプローチですか?」という質問への回答です(これはすべての人に無視されているようです)
要約:mdtimes
からペアワイズのものを作ることから、包括的問題(bigdata
のセグメント化)に視線を上げる必要があるかもしれません。
詳細:
結果の望ましい使用法は次のように表されます。
_datasegment = [x for x in bigdata if ( (x['datetime'] > tleft) and (x['datetime'] < tright))]
_
これは次のように表現されます。
_datasegment = [x for x in bigdata if tleft < x['datetime'] < tright]
_
現状では、タイムスタンプが境界点の1つと正確に等しい場合は含まれないため、次のように変更してみましょう。
_datasegment = [x for x in bigdata if tleft <= x['datetime'] < tright]
_
しかし、それはループに現れるでしょう:
_for tleft, tright in dtsegs:
datasegment = [x for x in bigdata if tleft <= x['datetime'] < tright]
do_something_with(datasegment)
_
おっと! len(bigdata) * len(dtsegs)
に比例して時間がかかります...len(bigdata)
とlen(dtsegs)
の値は何でしょうか?
bigdata
がソートされている場合、実行したいことはN
に比例する時間で実行できます。ここで、N = len(bigdata)
です。 bigdata
がまだソートされていない場合は、N * log(N)
に比例して時間でソートできます。
あなたは別の質問をしたいかもしれません...
タイムスタンプ<min(mdtimes)または> = max(mdtimes)を持つbigdata
内のアイテムは、どのデータセグメントにも含まれないことも指摘しておく価値があります...これは意図的なものですか?
私は専門家ではありませんが、リストをコピーしてから2つのリストから取得したペアの新しいリストを作成することで、メモリ要件を4倍にしませんか?次のことをしてみませんか。
dtsegs = [(dtg0[i], dtg0[i+1]) for i in range(len(dtg0)-1)]
でも、それがいかに「Pythonic」なのかわからない。
編集:実際、このタプルのリストで何をする必要があるかを見ると、この[i]と[i + 1]をそのレベルで直接実行でき、この新しい構造をまったく作成することさえできません。あなたが扱っている日付の数はわかりませんが、それが少し少ない場合は、実際には問題ではないと思います。
価値があるので、ここにいる他の回答者のカップルはあなたの質問を誤解しているようですが、私はまだ十分な評判を持っていないので彼らの投稿にコメントすることはできません:) Ignacio Vazquez-Abramsの解決策は私にとって最良のようです、彼の「next(dtg0)」はおそらく「next(dtg1)」(?)