2

以下の乱数を生成するコードを作成し、それらを以下のような csv に保存します。関数ごとにグループを試して学習しようとしています。たとえば、これらのグループの合計または平均をタイムスタンプで求めたいと思います。私はPythonが初めてですが、開始する場所が見つかりません。最終的には同じことをしたいのですが、1分または5分(00:00:00から始まる5分ごと、以下の例では十分なデータではありませんが、13:35:00から13:40:00のようになります)次の 13:40:00 が含まれて 13:45:00 が除外されるなど)、タイムスタンプから分の部分を抽出する際に 1 分を把握できると思いますが、5 分は複雑に見えます。コードのコピペを求めているわけではありませんが、正直なところどこから始めればよいかわかりません。

レベルのタイムスタンプ
99 2013/03/04 13:37:20
98 2013/03/04 13:37:20
98 2013/03/04 13:37:20
99 2013/03/04 13:37:20
105 2013/03/04 13:37:20
104 2013/03/04 13:37:20
102 2013/03/04 13:37:21
102 2013/03/04 13:37:21
103 2013/03/04 13:37:22
82 2013/03/04 13:37:23
83 2013/03/04 13:37:23
82 2013/03/04 13:37:23
83 2013/03/04 13:37:23
54 2013/03/04 13:37:24
55 2013/03/04 13:37:24
54 2013/03/04 13:37:24
55 2013/03/04 13:37:24
56 2013/03/04 13:37:25
57 2013/03/04 13:37:25
4

2 に答える 2

3

それは itertools http://docs.python.org/2/library/itertools.html#itertools.groupbyで行うことができます

しかし、気をつけてください:

キー関数の値が変更されるたびに、ブレークまたは新しいグループが生成されます (そのため、通常、同じキー関数を使用してデータを並べ替える必要があります)。

使用例:

データが Level とタイムスタンプのペアのリストとして処理されている場合。

data = [(99, '03/04/2013 13:37:20'), (98,  '03/04/2013 13:37:20'), ...]

そして、5分間隔のデータでグループをAVGしたいと思います

data.sort(key=lambda i: i[1]) # sort with timestamp
results = []

def keyfunc(timestamp, interval = 5*60):
    # defined a key function.
    # 1. parse the datetime string to datetime object
    # 2. count the time delta (seconds)
    # 3. divided the time delta with interval, which is (6*60) here
    xt = datetime(2013, 4,3)
    dt = datetime.strptime(timestamp, '%d/%m/%Y %H:%M:%S')
    delta_second = int((dt - xt).total_seconds())
    normalize_second = (delta_second / interval) * interval
    return xt + timedelta(seconds=normalize_second)

for k, g in groupby(data, key=lambda i: keyfunc(i[1])):
    # k would be time interval "03/04/2013 13:30:00", "03/04/2013 13:35:00" .... 
    # g would be the level, timestamp pair belong to the interval
    avg_level = sum([x[0] for x in g]) / len(g)
    results.append((k, avg_level))

編集1

groupbykeyfunc関数で使用されるは、アイテムをグループに分割する方法を示します。2 つのアイテムが同じキー関数の戻り値を持つ場合、それらは同じグループに配置されます。(これらの項目がソートされている場合のみ)

>>> keyfunc('03/04/2013 13:37:20')
datetime.datetime(2013, 4, 3, 13, 35)

>>> keyfunc('03/04/2013 13:37:30')
datetime.datetime(2013, 4, 3, 13, 35)

# the return value are the same, so 03/04/2013 13:37:20 and 03/04/2013 13:37:30
# will be consider in the same group. 
于 2013-04-03T15:58:06.193 に答える
0

これにアプローチする方法はいくつかありますが、効果的に時間を「ビニング」しています。私はいくつかのステップでそれにアプローチします:

文字列操作で時間を自分で解析したくない場合は、顔が爆発します。私を信じて!タイムスタンプを解析して datetime オブジェクトにします (Google はかなり良い答えを返すはずです)。それができたら、2回比較するなど、たくさんの楽しいことができます。

datetime オブジェクトを取得したので、それらを "ビン化" することができます。記録は整っていると思います。最初のレコードの時刻「2013/03/04 13:37:20」から開始し、「2013/03/04 13:37:00」に新しい日時オブジェクトを作成します [ヒント: 作成した日時オブジェクトに秒 = 0 を設定します。読む]。これが最初の「ビン」の始まりです。ここで、開始日時 [ヒント: endDT = startDT + timedelta(seconds=60)] に 1 分を追加します。これが最初のビンの終わりです。

レコードが endDT よりも小さいかどうかを確認し、そうであれば、そのビンのリストに追加します。レコードが endDT より大きい場合は、次のビンにいます。新しいビンを開始するには、endDT に 1 分を追加し、新しいリストを作成してそれらのアイテムを保持し、ループ内でチャグを続けます。

ループを通過したら、リストで max/min/avg を実行できます。{datetimeObject : [34, 23, 45, 23]} のような辞書にリストを格納するのが理想的です。印刷や仕分けが楽になります。

これは最も効率的/柔軟/クールな方法ではありませんが、おそらく最初から最も役立つ方法だと思います。

于 2013-04-03T15:40:41.490 に答える