首页 文章

如何将数组插入数据库?

提问于
浏览
15

In my previous question很多用户都希望我给玩具提供更多数据 . 所以我开始导出所有数据并用Python处理它,但后来我意识到:我在哪里留下所有这些数据?

好吧我决定把它们放在数据库中是最好的,所以至少我每次都没有to parse the raw files . 但由于我对数据库一无所知,因此结果令人困惑 . 我尝试了一些教程来创建一个sqlite数据库,添加一个表和字段并尝试插入我的numpy.arrays,但它无法让它工作 .

通常我的每只狗的结果如下所示:
alt text

所以我有35只不同的狗,每只狗有24个测量值 . 每个测量本身都有未知数量的联系人 . 每个测量由3D阵列(整个板的248帧[255x63])和2D阵列(板的每个传感器的最大值[255x63])组成 . 在数据库中存储一个值不是问题,但在那里获取我的2D数组似乎不起作用 .

所以我的问题是如何在数据库中订购并将数组插入其中?

6 回答

  • 7

    您可能希望从包含每只狗的所有扁平(非阵列)数据的 dogs 表开始,每只狗都有一个,比如姓名,性别和年龄:

    CREATE TABLE `dogs` (
      `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `name` VARCHAR(64),
      `age` INT UNSIGNED,
      `sex` ENUM('Male','Female')
    );
    

    从那里,每只狗"has many"测量,所以你需要一个 dog_mesaurements 表来存储24个测量值:

    CREATE TABLE `dog_measurements` (
      `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `dog_id` INT UNSIGNED NOT NULL,
      `paw` ENUM ('Front Left','Front Right','Rear Left','Rear Right'),
      `taken_at` DATETIME NOT NULL
    );
    

    那么每当你进行测量时,你 INSERT INTO dog_measurements (dog_id,taken_at) VALUES (*?*, NOW()); 哪里*? *是 dogs 表中的狗的ID .

    然后,您需要表格来存储每个测量的实际帧,例如:

    CREATE TABLE `dog_measurement_data` (
      `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `dog_measurement_id` INT UNSIGNED NOT NULL,
      `frame` INT UNSIGNED,
      `sensor_row` INT UNSIGNED,
      `sensor_col` INT UNSIGNED,
      `value` NUMBER
    );
    

    这样,对于250帧中的每一帧,您循环遍历63个传感器中的每一个,并将具有帧编号的该传感器的值存储到数据库中:

    INSERT INTO `dog_measurement_data` (`dog_measurement_id`,`frame`,`sensor_row`,`sensor_col`,`value`) VALUES
    (*measurement_id?*, *frame_number?*, *sensor_row?*, *sensor_col?*, *value?*)
    

    显然要替换measurement_id?,frame_number?,sensor_number ?, value?有实际 Value :-)

    所以基本上,每个 dog_measurement_data 是给定帧的单个传感器值 . 这样,为了获得所有给定帧的所有传感器值,您将:

    SELECT `sensor_row`,sensor_col`,`value` FROM `dog_measurement_data`
    WHERE `dog_measurement_id`=*some measurement id* AND `frame`=*some frame number*
    ORDER BY `sensor_row`,`sensor_col`
    

    这将为您提供该帧的所有行和列 .

  • 1

    Django有一个库,用于将所有数据库工作封装到Python类中,因此在必须做一些非常聪明的事情之前,您不必乱用原始SQL . 尽管Django是Web应用程序的框架,但您可以use the database ORM by itself .

    Josh的模型在使用Django的Python中看起来像这样:

    from django.db import models
    
    class Dog(models.Model):
        # Might want to look at storing birthday instead of age.
        # If you track age, you probably need another field telling
        # you when in the year age goes up by 1... and at that point,
        # you're really storing a birthday.
        name = models.CharField(max_length=64)
        age = models.IntegerField()
        genders = [
            ('M', 'Male'),
            ('F', 'Female'),
        ]
        gender = models.CharField(max_length=1, choices=genders)
    
    class Measurement(models.Model):
        dog = models.ForeignKey(Dog, related_name="measurements")
        paws = [
            ('FL', 'Front Left'),
            ('FR', 'Front Right'),
            ('RL', 'Rear Left'),
            ('RR', 'Rear Right'),
        ]
        paw = models.CharField(max_length=2, choices=paws)
        taken_at = models.DateTimeField(default=date, auto_now_add=True)
    
    class Measurement_Point(models.Model):
        measurement = models.ForeignKey(Measurement, related_name="data_points")
        frame = models.IntegerField()
        sensor_row = models.PositiveIntegerField()
        sensor_col = models.PositiveIntegerField()
        value = models.FloatField()
    
        class Meta:
            ordering = ['frame', 'sensor_row', 'sensor_col']
    

    id 字段是自动创建的 .

    然后你可以做以下事情:

    dog = Dog()
    dog.name = "Pochi"
    dog.age = 3
    dog.gender = 'M'
    # dog.gender will return 'M', and dog.get_gender_display() will return 'Male'
    dog.save()
    
    # Or, written another way:
    dog = Dog.objects.create(name="Fido", age=3, sex='M')
    

    要进行测量:

    measurement = dog.measurements.create(paw='FL')
    for frame in range(248):
        for row in range(255):
            for col in range(63):
                measurement.data_points.create(frame=frame, sensor_row=row, 
                    sensor_col=col, value=myData[frame][row][col])
    

    最后,获得一个框架:

    # For the sake of argument, assuming the dogs have unique names.
    # If not, you'll need some more fields in the Dog model to disambiguate.
    dog = Dog.objects.get(name="Pochi", sex='M')
    # For example, grab the latest measurement...
    measurement = dog.measurements.all().order_by('-taken_at')[0]
    # `theFrameNumber` has to be set somewhere...
    theFrame = measurement.filter(frame=theFrameNumber).values_list('value')
    

    注意:这将返回元组列表(例如 [(1.5,), (1.8,), ... ] ),因为 values_list() 可以一次检索多个字段 . 我想象一下将向量重映射到矩阵的函数's got a function similar to Matlab' s reshape .

  • 2

    我想你无法弄清楚如何将2D数据放入数据库 .

    如果考虑2列之间的关系,可以将其视为2D数据,第1列为X轴数据,第2列为Y轴数据 . 同样适用于3D数据 .

    最后你的db应该是这样的:

    Table: Dogs
        Columns: DogId, DogName -- contains data for each dog
    
    Table: Measurements
        Columns: DogId, MeasurementId, 3D_DataId, 2D_DataId -- contains measurements of each dog
    
    Table: 3D_data
        Columns: 3D_DataId, 3D_X, 3D_Y, 3D_Z -- contains all 3D data of a measurement
    
    Table: 2D_data
        Columns: 2D_DataId, 2D_X, 2D_Y -- contains all 2D data of a measurement
    

    此外,您可能希望按顺序存储3D数据和2D数据 . 在这种情况下,您必须添加一列以在3D数据和2D数据表中存储该顺序

  • 0

    我要添加到Josh的唯一答案是,如果您不需要查询单个帧或传感器,只需将数组存储为dog_measurement_data表中的BLOB . 之前我已经使用大量的二进制传感器数据集完成了这项工作并且运行良好 . 您基本上在每次测量时查询2d和3d数组,并在代码而不是数据库中操作它们 .

  • 2

    我从_1180173中受益匪浅;它是一个对象关系映射器 . 这意味着您可以在对象和数据之间创建一个非常清晰明确的分离:

    SQL数据库的行为不像对象集合,更大的尺寸和性能开始变得重要;对象集合的行为不像表和行,抽象开始变得越来越重要 . SQLAlchemy旨在适应这两个原则 .

    您可以创建表示不同名词的对象(狗,测量,板等) . 然后通过 sqlalchemy 构造创建一个表,该构造将包含要与之关联的所有数据,例如 Dog 对象 . 最后,在 Dog 对象和 dog_table 之间创建 mapper .

    这很难理解没有例子,我不会在这里重现一个 . 相反,请先阅读this case study,然后研究this tutorial .

    一旦你能够像在现实世界中那样想到你的 DogsMeasurements (也就是对象本身),你就可以开始将构成它们的数据分解出来 .

    最后,尽量不要将数据与特定格式结合(正如您目前使用 numpy 数组所做的那样) . 相反,您可以考虑简单的数字,然后根据需要将它们转换为您当前应用程序所需的特定格式(沿着模型 - 视图 - 控制器范例的行) .

    祝好运!

  • 9

    根据您的描述,我强烈建议您查看PyTables . 它可能正在使用(例如查询),同时允许轻松存储大型,多维数据集及其属性 . 作为额外的奖励,它与numpy紧密结合 .

相关问题