2010-09-17 35 views
12

In my previous question rất nhiều người dùng muốn tôi cung cấp thêm một số dữ liệu để chơi cùng. Vì vậy, tôi đã làm việc trên xuất khẩu tất cả các dữ liệu của tôi và xử lý nó với Python, nhưng sau đó tôi nhận ra: nơi nào tôi để lại tất cả các dữ liệu này?Làm thế nào để chèn mảng vào cơ sở dữ liệu?

Tôi đã quyết định điều tốt nhất là gắn chúng vào cơ sở dữ liệu, vì vậy ít nhất tôi không có to parse the raw files mỗi lần. Nhưng vì tôi không biết gì về cơ sở dữ liệu nên việc này khá khó hiểu. Tôi đã thử một số hướng dẫn để tạo ra một cơ sở dữ liệu sqlite, thêm một bảng và lĩnh vực và cố gắng để chèn numpy.arrays của tôi, nhưng nó không thể làm cho nó hoạt động.

Điển hình là kết quả của tôi mỗi con chó trông như thế này: alt text

Vì vậy, tôi có 35 con chó khác nhau và mỗi con chó có 24 phép đo. Mỗi bản thân phép đo có số lượng địa chỉ liên lạc không xác định. Mỗi phép đo bao gồm một mảng 3D (248 khung của toàn bộ tấm [255x63]) và một mảng 2D (giá trị tối đa cho mỗi cảm biến của tấm [255x63]). Lưu trữ một giá trị trong một cơ sở dữ liệu không phải là một vấn đề, nhưng nhận được mảng 2D của tôi ở đó dường như không hoạt động.

Vì vậy, câu hỏi của tôi là làm thế nào tôi nên đặt hàng này trong một cơ sở dữ liệu và chèn mảng của tôi vào nó?

+0

Để tiết lộ đầy đủ, điều này đang được thảo luận trong [SuperUser Chat] (http://chat.superuser.com/rooms/11/fake-programmers) ngay bây giờ :-) – Josh

+0

Lý do chính là tôi không sẽ là người sử dụng nó và tôi cần một số đảm bảo rằng các tệp của tôi là nơi tôi đặt chúng. Plus rõ ràng là tôi sẽ chèn nhiều dữ liệu hơn, không chỉ các mảng này. Nhưng các mảng đang khiến tôi đau đầu, vì vậy nếu tôi có thể nhận được những điều này, phần còn lại sẽ dễ dàng hơn –

+2

Tại sao không sử dụng pickle.dump hoặc numpy.dump thay thế? Sau đó, bạn chỉ có thể đổ toàn bộ mảng đa chiều của bạn. Không có lý do gì để thiết kế một cơ sở dữ liệu nếu bạn chỉ sử dụng nó để duy trì các đối tượng python. –

Trả lời

8

Bạn có thể muốn bắt đầu với bảng dogs chứa tất cả dữ liệu phẳng (không mảng) cho mỗi chú chó, những thứ mà mỗi chú chó có một số, như tên, giới tính và độ tuổi:

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

Từ đó, mỗi con chó "có nhiều" phép đo, vì vậy bạn cần một bảng dog_mesaurements để lưu trữ 24 đo:

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

Sau đó, bất cứ khi nào bạn có một phép đo, bạn INSERT INTO dog_measurements (dog_id,taken_at) VALUES (*?*, NOW()); wher e * ? * là ID của chó từ bảng dogs.

Sau đó bạn sẽ muốn bảng để lưu trữ các khung hình thực tế cho mỗi lần đo, một cái gì đó như:

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

Bằng cách đó, cho mỗi 250 khung hình, bạn lặp qua mỗi trong số 63 cảm biến, và lưu trữ giá trị cho cảm biến đó với số khung vào cơ sở dữ liệu:

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

Rõ ràng thay thế measurement_id?, frame_number?, sensor_number?, giá trị? với giá trị thực :-)

Vì vậy, về cơ bản, mỗi dog_measurement_data là giá trị cảm biến đơn cho một khung nhất định. Bằng cách đó, để có được tất cả giá trị cảm biến cho tất cả một khung nhất định, bạn sẽ:

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` 

Và điều này sẽ cung cấp cho bạn tất cả các hàng và cột cho khung đó.

+4

Mặc dù, cho 'chân' bạn có thể muốn một cái gì đó chung chung hơn nói, "phần phụ". Sau đó, bạn có thể có nó cũng là một int unsigned cho các loài nhện lớn, decapods, zerg, vv ... – Tyler

+0

@ Tyler: Nói chung đó là lời khuyên tuyệt vời. Trong trường hợp này, Ivo đang làm việc trên phần mềm đặc biệt cho chó, nhưng ai biết được, bác sĩ thú y có thể nhận được một số Zergs trong tháng tới! – Josh

+0

Woops @Josh, tôi đã thử câu lệnh chèn của bạn và mất 6 phút để chèn một phép đo :-P Đoán tôi nên điều chỉnh nó để sử dụng hàm thực thi() thay vào đó! Và nếu bạn có thời gian, [chào mừng bạn đến với các lập trình viên giả mạo] (http://chat.stackexchange.com/rooms/116/fake-programmers) –

2

Tôi nghĩ bạn không thể tìm ra cách đưa dữ liệu 2D vào cơ sở dữ liệu.

Nếu bạn nghĩ về mối quan hệ giữa 2 cột, bạn có thể coi nó là dữ liệu 2D với cột thứ nhất là dữ liệu trục X và cột thứ 2 là dữ liệu trục Y. Tương tự cho dữ liệu 3D.

Cuối cùng db của bạn sẽ giống như thế này:

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 

Ngoài ra bạn có thể muốn lưu trữ dữ liệu 3D của bạn và dữ liệu 2D trong một trật tự. Trong trường hợp đó, bạn sẽ phải thêm cột để lưu trữ thứ tự đó trong bảng dữ liệu 3D và dữ liệu 2D

2

Điều duy nhất tôi thêm vào câu trả lời của Josh là nếu bạn không cần truy vấn khung hoặc cảm biến riêng lẻ , chỉ lưu trữ các mảng dưới dạng BLOB trong bảng dog_measurement_data. Tôi đã làm điều này trước đây với bộ dữ liệu cảm biến nhị phân lớn và nó hoạt động tốt. Về cơ bản, bạn truy vấn mảng 2d và 3d với mỗi phép đo và thao tác chúng trong mã thay vì cơ sở dữ liệu.

+0

Điều này lẽ ra đã được đăng tải dưới dạng bình luận cho câu trả lời của tôi, nhưng , Tôi đoán bạn không thể đăng bình luận :-) Đáp lại, tôi muốn nói rằng nhược điểm này là, bạn cần một định dạng mà bạn có thể lưu trữ một cách đáng tin cậy từ BLOB, như JSON hoặc một số giá trị python được tuần tự hóa khác. Điều này có thể không dễ dàng như nó nghe! – Josh

7

Django có thư viện để đóng gói tất cả các công việc cơ sở dữ liệu vào các lớp Python, vì vậy bạn không phải lộn xộn với SQL thô cho đến khi bạn phải làm điều gì đó thực sự thông minh. Mặc dù Django là một khuôn khổ cho các ứng dụng web, bạn có thể use the database ORM by itself.

mô hình của Josh sẽ trông như thế này trong Python sử dụng 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'] 

Các trường id được tạo ra tự động.

Sau đó, bạn có thể làm những việc như:

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

Để chụp đo:

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

Cuối cùng, để có được một khung:

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

Lưu ý: đây sẽ trả về một danh sách các bộ dữ liệu (ví dụ: [(1.5,), (1.8,), ... ]), vì values_list() có thể truy xuất nhiều trường cùng một lúc. Tôi không quen thuộc với NumPy, nhưng tôi muốn tưởng tượng nó có một chức năng tương tự như chức năng reshape của Matlab để ánh xạ lại vectơ tới ma trận.

1

Tôi đã được hưởng lợi rất nhiều từ số sqlalchemy package; nó là một Mapper Relational Object. Điều này có nghĩa là bạn có thể tạo ra một sự tách biệt rất rõ ràng và khác biệt giữa các đối tượng của bạn và dữ liệu của bạn:

cơ sở dữ liệu SQL cư xử kém như đối tượng bộ sưu tập kích thước ngày càng bắt đầu thực hiện để thành vấn đề; đối tượng bộ sưu tập hoạt động ít hơn như bảng và các hàng trừu tượng hơn bắt đầu cho vấn đề. SQLAlchemy nhằm mục đích chứa cả hai nguyên tắc này.

Bạn có thể tạo một đối tượng đại diện cho các danh từ khác nhau của bạn (Chó, Đo lường, Đĩa, v.v.). Sau đó, bạn tạo một bảng thông qua các cấu trúc sqlalchemy sẽ chứa tất cả dữ liệu mà bạn muốn liên kết với đối tượng Dog. Cuối cùng, bạn tạo một mapper giữa đối tượng Dogdog_table.

Điều này rất khó hiểu mà không có ví dụ, và tôi sẽ không tái tạo ở đây. Thay vào đó, hãy bắt đầu bằng cách đọc this case study và sau đó nghiên cứu this tutorial.

Khi bạn có thể nghĩ về DogsMeasurements như bạn làm trong thế giới thực (nghĩa là, bản thân đối tượng), bạn có thể bắt đầu tính toán dữ liệu tạo nên chúng.

Cuối cùng, cố gắng không kết hôn với dữ liệu của bạn bằng một định dạng cụ thể (như bạn hiện đang sử dụng numpy mảng). Thay vào đó, bạn có thể nghĩ về các số đơn giản và sau đó biến chúng theo yêu cầu sang định dạng cụ thể mà ứng dụng hiện tại của bạn yêu cầu (dọc theo các dòng của mô hình Model-View-Controller).

Chúc may mắn!

0

Từ mô tả của bạn, tôi rất muốn giới thiệu xem xét PyTables. Nó không phải là một cơ sở dữ liệu quan hệ theo nghĩa truyền thống, nó có hầu hết các tính năng bạn có thể đang sử dụng (ví dụ truy vấn) trong khi cho phép lưu trữ dễ dàng các tập dữ liệu đa chiều và lớn và các thuộc tính của chúng. Là một tiền thưởng thêm, nó được tích hợp chặt chẽ với một chút.

Các vấn đề liên quan