7

恐ろしいタイトルですが、説明させてください。タイムスタンプ(日付)と、リソースを消費するユーザーの数をログに記録する属性(値)を含むこのdjangoモデルがあります。

class Viewers(models.Model):
    date = models.DateTimeField()
    value = models.IntegerField()

テーブルには 10 秒ごとにユーザー数が含まれます。このようなもの:

| date | value |
|------|-------|
|  t1  |   15  |
|  t2  |   18  |
|  t3  |   27  |
|  t4  |   25  |
|  ..  |   ..  |
|  t30 |   38  |
|  t31 |   36  |
|  ..  |   ..  |

今、私はこのデータからそれぞれ別の解像度で異なる統計を生成したいと考えています。最後の日のグラフの場合、10 秒の解像度は必要ないので、t1 から t29、t30 から t59 までの行の値 (およびおそらく日付) を平均することによって作成される 5 分のステップが必要です。 ...)、私が得られるように:

| date | value |
|------|-------|
|  t15 |   21  |
|  t45 |   32  |
|  ..  |   ..  |

変数を保持する属性は、開始と終了のタイムスタンプと解像度 (5 分など) です。django orm/queryset APIを使用する方法はありますか?そうでない場合、カスタムSQLでこれに到達する方法はありますか?

4

4 に答える 4

4

私はこの問題を可能な限り「ジャンゴ」の方法で解決しようとしています。以下に落ち着きました。start_date と end_date の間の 15 分間のタイム スロットの値を平均します。列名は「date」です。

readings = Reading.objects.filter(date__range=(start_date, end_date)) \
   .extra(select={'date_slice': "FLOOR (EXTRACT (EPOCH FROM date) / '900' )"}) \
   .values('date_slice') \
   .annotate(value_avg=Avg('value'))

辞書を返します。

 {'value_avg': 1116.4925373134329, 'date_slice': 1546512.0}
 {'value_avg': 1001.2028985507246, 'date_slice': 1546513.0}
 {'value_avg': 1180.6285714285714, 'date_slice': 1546514.0}

アイデアの核心は、 PHP/SQL の同じ質問に対するこの回答から来ています。extra に渡されるコードは、Postgres DB 用です。

于 2014-02-12T23:06:36.680 に答える
2
from django.db.models import Avg

Viewers.objects.filter(date__range=(start_time, end_time)).aggregate(average=Avg('value'))

これにより、とのvalues間のすべての平均が取得され、 の形式で辞書として返されます。start_timeend_time{ 'average': <the average> }

start_timePython の datetime オブジェクトでend_timeある必要があります。したがって、タイムスタンプなどがある場合は、最初に変換する必要があります。start_time に基づいてdatetime.timedeltaを計算するために使用することもできます。end_time5 分間の解像度の場合、次のようになります。

from datetime import timedelta

end_time = start_time + timedelta(minutes=5)
于 2011-06-07T15:02:39.910 に答える
1

範囲フィルターを見ましたか?

https://docs.djangoproject.com/en/dev/ref/models/querysets/#range

ドキュメントに示されている例は、あなたの状況に似ているようです。

于 2011-06-07T14:50:10.723 に答える
-1

長い間試した後、SQLステートメントとして作成しました:

SELECT FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(date))), SUM(value)
FROM `my_table`
WHERE date BETWEEN SUBTIME(NOW( ), '0:30:00') AND NOW()
GROUP BY UNIX_TIMESTAMP(date) DIV 300
ORDER BY date DESC

start_time = SUBTIME(NOW( ), '0:30:00')
end_time = NOW()
period = 300 # in seconds

最後に - 本当に難しいことではありません - 実際、元のテーブルのサンプリングの時間分解能とは無関係です。

于 2011-06-08T07:03:07.900 に答える