用于时间序列数据的Django数据库结构?

我正在开发一个应用程序,允许用户选择一个海洋浮标,然后通过交互式绘图绘制其历史时间序列数据。我的最终目标是用户可以输入一个位置,然后加载浮标的数据,然后用户可以选择要绘制其数据的过滤器(因此基本上是仪表板)。例如,也许他们只想查看8月份发生的大于1英尺的隆起。

我知道如何使用pandas和plotly来做到这一点,但是我正在努力将其转移到django数据库框架中。

代码当前创建具有数据属性的浮标对象。此数据属性是一个字典,其结构如下:

{'stdmet':{'meta':{dictionary of metadata},'data':[pandas dataframe of time series data]}}

我将数据保存在pandas数据框中,因为它使我可以轻松地操作和创建绘图交互图。

我的问题是如何将其保存到Django模型中?我认为我应该有一个浮标类,其中包含用于元数据的字段(例如,浮标ID,纬度/经度等),然后我想为时间序列数据提供一个最终字段。我希望此字段保留为2D pandas数据框。

我认为此方法理想的另一个原因是,它不会为每次测量都创建一个新的浮标对象。相反,浮标对象将包含其内部所有历史测量值的2D数据框。这看起来更干净。

对此有任何建议,将不胜感激!

mj40778 回答:用于时间序列数据的Django数据库结构?

这里的标准方法是使用Django模型(转换为db中的表):

  • Buoy
  • BuoyData

BuoyData类将具有ForeignKey模型的Buoy

还要查看GeoDjango,以存储和查询经纬度。您将要使用PointField中的django.contrib.gis.db.models。以下是一些示例模型:

from django.contrib.gis.db import models


class Buoy(models.Model):
    """
    Represents a Buoy
    """
    location = models.PointField()
    name = models.CharField(max_length=200,null=True,blank=True)


class BuoyData(models.Model):
    """
    Represents a single Buoy datapoint
    """
    buoy = models.ForeignKey(Buoy,related_name='data')
    date = models.DateTimeField()
    # swell size in feet
    swell_size_ft = models.DecimalField(decimal_places=2,max_digits=5)

然后您可以在经度或纬度附近或附近查询Buoy,然后查询Buoy的数据。

django_pandas软件包具有将Django Queryset读取到Pandas数据框中的非常有用的方法:

from django_pandas.io import read_frame

buoy = Buoy.objects.get(id=10)
data_queryset = buoy.data.all()
df = read_frame(data_queryset)

# or another example
import datetime
from django.utils import timezone
from django.contrib.gis.geos import Point

lat = 36.123
lng = -121.123
# notice how lng is x,lat is y
location = Point(lng,lat)

time_four_days_ago = timezone.now() - datetime.timedelta(days=4)

closest_buoy = Buoy.objects.distance(location).order_by('distance')[0]
data_queryset = buoy.data.filter(date__gte=time_four_days_ago)

# if there are a lot of fields on your BuoyData model,# and you only need a few,.values will be more performant
data_values = data_queryset.values('date','swell_size_ft')
df = read_frame(data_values)

为什么您的方法无效:

关系数据库(MySQL,Postgresql)通常将数据存储在固定大小的空间中。浮标可能有数百万个时间序列数据点,并且可能每隔几秒钟添加一次新数据。您不知道单个浮标的所有将来数据会有多大。

设置数据库时,您需要为特定模型的每个字段设置大小上限。例如,文本字段具有max_length属性。当然,某些类型的字段支持非常大的最大大小,但这会影响数据库的性能。

相反,您需要创建一个单独的表来存储所有数据Buoys。该表中的每一行都是单独的时间序列数据。此数据库中的一个字段(列)将是数据所属的id中的Buoy。此字段由Django ForeignKey自动创建和填充。

,

截至 2021 年,现在有一个库可以将简单的时间序列向量作为自定义 Django 字段存储在数据库中:django-simple-timeseries

class Buoy(models.Model):
  location = models.PointField()
  name = models.CharField(max_length=200,blank=True)
  swell_size_ft = TimeseriesField(max_points=100,resolution_seconds=3600)

这对于小时间序列来说是一个方便的选项,并且可以安全地截断数据(在 max_points 之后)。

(免责声明:我根据自己的需要编写了这个库,这与提问者的类似。)

本文链接:https://www.f2er.com/3070660.html

大家都在问