¿Cómo insertar matrices en una base de datos?

En mi pregunta anterior, muchos usuarios querían que diera más datos para jugar. Así que comencé a exportar todos mis datos y procesarlos con Python, pero luego me di cuenta: ¿dónde dejo todos estos datos?

Bueno, decidí que lo mejor sería guardarlos en una base de datos, así que al menos no tengo que analizar los archivos en bruto cada vez. Pero como no sé nada acerca de las bases de datos, esto está resultando bastante confuso. Intenté algunos tutoriales para crear una base de datos sqlite, agregar una tabla y un campo e intentar insertar mi numpy.arrays, pero no puedo hacer que funcione.

Típicamente mis resultados por perro se ven así: texto alternativo

Así que tengo 35 perros diferentes y cada perro tiene 24 medidas. Cada medida en sí tiene una cantidad desconocida de contactos. Cada medición consiste en una matriz 3D (248 cuadros de la placa completa [255×63]) y una matriz 2D (los valores máximos para cada sensor de la placa [255×63]). El almacenamiento de un valor en una base de datos no fue un problema, pero el hecho de tener mis matrices 2D allí no pareció funcionar.

Entonces, mi pregunta es ¿cómo debo ordenar esto en una base de datos e insertar mis arreglos en ella?

Django tiene una biblioteca para encapsular todo el trabajo de base de datos en clases de Python, por lo que no tiene que meterse con el SQL en bruto hasta que tenga que hacer algo realmente inteligente. Aunque Django es un marco para aplicaciones web, puede utilizar la base de datos ORM por sí misma .

Los modelos de Josh se verían así en Python usando Django:

 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'] 

Los campos de id se crean automáticamente.

Entonces puedes hacer cosas como:

 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') 

Para tomar una medida:

 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]) 

Finalmente, para obtener un marco:

 # 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') 

Nota: esto devolverá una lista de tuplas (por ejemplo, [(1.5,), (1.8,), ... ] ), ya que values_list() puede recuperar varios campos a la vez. No estoy familiarizado con NumPy, pero me imagino que tiene una función similar a la función de reshape de Matlab para volver a correlacionar vectores con matrices.

Creo que no puedes descubrir cómo colocar datos 2D en una base de datos.

Si piensa en la relación entre 2 columnas, puede considerarla como datos 2D con la 1ra columna como datos del eje X y la 2ª columna como datos del eje Y. Del mismo modo para los datos en 3D.

Finalmente tu db debería verse así:

 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 

También es posible que desee almacenar sus datos 3D y datos 2D en un pedido. En ese caso, tendrá que agregar una columna para almacenar ese orden en la tabla de datos 3D y datos 2D

Lo único que agregaría a la respuesta de Josh es que si no necesita consultar marcos o sensores individuales, simplemente almacene los arreglos como BLOB en la tabla dog_measurement_data. He hecho esto antes con un gran conjunto binario de datos de sensores y funcionó bien. Básicamente, consulta las matrices 2d y 3d con cada medición y las manipula en el código en lugar de en la base de datos.

Me he beneficiado mucho del paquete sqlalchemy ; Es un Mapeador Relacional de Objetos. Lo que esto significa es que puede crear una separación muy clara y clara entre sus objetos y sus datos:

Las bases de datos SQL se comportan menos como las colecciones de objetos, mientras más tamaño y rendimiento comienzan a importar; las colecciones de objetos se comportan menos como tablas y filas, mientras más abstracción comienza a importar. SQLAlchemy tiene como objective dar cabida a estos dos principios.

Puede crear objetos que representen sus diferentes nombres (Perro, Medición, Placa, etc.). Luego, crea una tabla a través de construcciones sqlalchemy que contendrá todos los datos que desea asociar, por ejemplo, con un objeto Dog . Finalmente, creas un mapper entre el objeto Dog y la dog_table .

Esto es difícil de entender sin un ejemplo, y no reproduciré uno aquí. En su lugar, comienza leyendo este estudio de caso y luego estudia este tutorial .

Una vez que pueda pensar en sus Dogs y Measurements como lo hace en el mundo real (es decir, los objetos mismos), puede comenzar a factorizar los datos que los componen.

Finalmente, intente no combinar sus datos con un formato específico (como lo hace actualmente mediante el uso de matrices numpy ). En su lugar, puede pensar en los números simples y luego transformarlos según la demanda al formato específico que exige su aplicación actual (en la línea de un paradigma Modelo-Vista-Controlador).

¡Buena suerte!

Desde su descripción, recomendaría encarecidamente buscar en PyTables . No es una base de datos relacional en el sentido tradicional, tiene la mayoría de las características que es probable que esté utilizando (por ejemplo, la consulta) al tiempo que permite el almacenamiento fácil de grandes conjuntos de datos multidimensionales y sus atributos. Como un bono adicional, está perfectamente integrado con numpy.