2010-10-26 36 views
6

Gần đây tôi đã bắt gặp Pytables và thấy nó rất tuyệt. Rõ ràng là chúng vượt trội hơn định dạng csv cho các tập dữ liệu rất lớn. Tôi đang chạy một số mô phỏng bằng cách sử dụng python. Đầu ra không quá lớn, nói 200 cột và 2000 hàng.Pytables so với CSV cho các tệp không quá lớn

Nếu ai đó có kinh nghiệm với cả hai, bạn có thể đề xuất định dạng nào thuận tiện hơn về lâu dài cho các tập dữ liệu đó không phải là rất lớn. Pytables có khả năng thao tác dữ liệu và duyệt dữ liệu với Vitables, nhưng trình duyệt không có nhiều chức năng như Excel nói, có thể được sử dụng cho CSV. Tương tự như vậy, bạn có tìm thấy một cái tốt hơn cái kia để nhập và xuất dữ liệu, nếu làm việc chủ yếu trong python? Là một trong những thuận tiện hơn về tổ chức tập tin? Bất kỳ ý kiến ​​về các vấn đề như thế này sẽ hữu ích.

Cảm ơn.

+1

Điều này có thể phụ thuộc vào những gì bạn đang làm với dữ liệu - tức là bạn định nghĩa sự tiện lợi như thế nào. Bạn có 1. Bạn muốn xem dữ liệu với một trình soạn thảo trực quan tốt bất cứ khi nào bạn muốn 2. Có thể kiểm tra dữ liệu một lần trực quan và sau đó chuyển nó vào một số chương trình khác? Nếu bạn muốn đầu tiên và cần chức năng đó để 'xem' dữ liệu thì định dạng csv có lẽ không phải là một lựa chọn tồi. Cho 2, pytables có lẽ là tốt. Trong cả hai trường hợp, dữ liệu của bạn nhỏ, tại sao không lưu cả hai? – Marm0t

Trả lời

5

Bạn có coi mảng Numpy không?

PyTables là tuyệt vời khi dữ liệu của bạn quá lớn để vừa với bộ nhớ, nhưng ma trận 200x2000 của 8 byte nổi chỉ yêu cầu khoảng 3MB bộ nhớ. Vì vậy, tôi nghĩ rằng PyTables có thể quá mức cần thiết.

Bạn có thể lưu mảng cố định vào tệp bằng cách sử dụng np.savetxt hoặc np.savez (để nén) và có thể đọc chúng từ các tệp có np.loadtxt hoặc np.load.

Nếu bạn có nhiều mảng như vậy để lưu trữ trên đĩa, thì tôi khuyên bạn nên sử dụng cơ sở dữ liệu thay vì các tập tin .npz khó khăn. Bằng cách này, để lưu trữ một ma trận 200x2000 trong một cơ sở dữ liệu, bạn chỉ cần 3 cột của bảng: row, col, giá trị:

import sqlite3 
import numpy as np 

db = sqlite3.connect(':memory:') 
cursor = db.cursor() 
cursor.execute('''CREATE TABLE foo 
        (row INTEGER, 
        col INTEGER, 
        value FLOAT, 
        PRIMARY KEY (row,col))''') 
ROWS=4 
COLUMNS=6 
matrix = np.random.random((ROWS,COLUMNS)) 
print(matrix) 
# [[ 0.87050721 0.22395398 0.19473001 0.14597821 0.02363803 0.20299432] 
# [ 0.11744885 0.61332597 0.19860043 0.91995295 0.84857095 0.53863863] 
# [ 0.8.52689885 0.05861043 0.71784406 0.20222138 0.63094807] 
# [ 0.01309897 0.45391578 0.04950273 0.93040381 0.41150517 0.66263562]] 

# Store matrix in table foo 
cursor.executemany('INSERT INTO foo(row, col, value) VALUES (?,?,?) ', 
        ((r,c,value) for r,row in enumerate(matrix) 
           for c,value in enumerate(row))) 

# Retrieve matrix from table foo 
cursor.execute('SELECT value FROM foo ORDER BY row,col') 
data=zip(*cursor.fetchall())[0] 
matrix2 = np.fromiter(data,dtype=np.float).reshape((ROWS,COLUMNS)) 
print(matrix2) 
# [[ 0.87050721 0.22395398 0.19473001 0.14597821 0.02363803 0.20299432] 
# [ 0.11744885 0.61332597 0.19860043 0.91995295 0.84857095 0.53863863] 
# [ 0.8.52689885 0.05861043 0.71784406 0.20222138 0.63094807] 
# [ 0.01309897 0.45391578 0.04950273 0.93040381 0.41150517 0.66263562]] 

Nếu bạn có nhiều 200x2000 ma trận như vậy, bạn chỉ cần thêm một cột bảng để xác định ma trận nào.

+0

Điều này nghe có vẻ thú vị. Tôi không biết nhiều về cơ sở dữ liệu, nhưng sẽ xem xét điều này và đăng lại. Những gì không rõ ràng với tôi từ ví dụ của bạn là làm thế nào là các tọa độ của mỗi giá trị trong 2000 hàng x 200 cột ma trận đang được gán cho bảng cơ sở dữ liệu. Tôi sẽ cố gắng tìm ra điều đó. – Curious2learn

+0

Tôi không nghĩ rằng tôi muốn sử dụng một cột 'id' riêng biệt cho khóa chính. hàng/cột tạo ra khóa chính tốt hơn nhiều, vì nó thực sự là nhận dạng cho bit dữ liệu đó. đối với ma trận 2000x2000, bạn thậm chí có thể khéo léo và đóng gói cả hàng và cột vào cùng một cột số nguyên, giống như 'hàng << 16 + col'. – SingleNegationElimination

+0

@TokenMacGuy: Cảm ơn bạn! – unutbu

0

Đây không phải là lựa chọn "độc quyền".

Bạn cần cả hai.

CSV chỉ là một định dạng trao đổi dữ liệu. Nếu bạn sử dụng pytables, bạn vẫn cần nhập và xuất ở định dạng CSV.

+0

Bạn có thể vui lòng xây dựng? Tôi không cần phải tạo tệp CSV để sử dụng các pytables. Cảm ơn! – Curious2learn

+0

Bạn cần tạo CSV để trao đổi dữ liệu với các ứng dụng chỉ chấp nhận CSV. Ví dụ: bảng tính. –

2

Theo như nhập/xuất, PyTables sử dụng định dạng tệp chuẩn được gọi là HDF5. Nhiều gói phần mềm khoa học (như MATLAB) đã tích hợp sẵn hỗ trợ cho HDF5 và API C không phải là khủng khiếp. Vì vậy, bất kỳ dữ liệu nào bạn cần xuất từ ​​hoặc nhập vào một trong những ngôn ngữ này có thể được lưu giữ đơn giản trong các tệp HDF5.

PyTables có thể thêm một số thuộc tính của riêng nó, nhưng chúng không làm bạn đau. Tất nhiên, nếu bạn lưu trữ các đối tượng Python trong tệp, bạn sẽ không thể đọc chúng ở nơi khác.

Điều tuyệt vời nhất về tệp CSV là chúng có thể đọc được. Tuy nhiên, nếu bạn cần lưu trữ bất cứ điều gì khác hơn là số đơn giản trong họ và giao tiếp với người khác, bạn sẽ có vấn đề. Tôi nhận được tệp CSV từ những người trong các tổ chức khác và tôi nhận thấy rằng con người không giỏi đảm bảo những thứ như trích dẫn chuỗi được thực hiện chính xác. Thật tốt khi trình phân tích cú pháp CSV của Python linh hoạt như vậy. Một vấn đề khác là các số dấu phẩy động không thể được lưu trữ chính xác trong văn bản sử dụng định dạng thập phân. Nó thường là đủ tốt, mặc dù.

+0

Cảm ơn bạn đã phản hồi! Bạn có nói rằng với ViTables, ngay cả PyTables cũng trở nên dễ đọc. – Curious2learn

+0

ViTables thật tuyệt vời. NHƯNG, nó là một cái gì đó của một nỗi đau để cài đặt (cho đến khi có lẽ gần đây). –

+0

float * có thể * được lưu trữ chính xác trong số thập phân ascii, nhưng yêu cầu khá một vài chữ số thập phân để làm như vậy. Điều này thường không phải là mặc định cho định dạng chuỗi của phao, mặc dù. – SingleNegationElimination

1

tôi nghĩ rằng nó rất khó để comapre pytables và csv .. pyTable là một datastructure ehile CSV là một định dạng trao đổi dữ liệu.

1

Đây thực sự là khá liên quan đến một câu trả lời tôi đã cung cấp liên quan đến các file csv đọc/ghi w/NumPy:

Python: how to do basic data manipulation like in R?

Bạn nên chắc chắn sử dụng NumPy, không có vấn đề gì khác! Sự dễ dàng lập chỉ mục, vv vượt xa chi phí của sự phụ thuộc bổ sung (tốt, tôi nghĩ vậy). PyTables, tất nhiên, cũng phụ thuộc vào quá nhiều.

Nếu không, điều đó thực sự tùy thuộc vào ứng dụng, phần cứng và đối tượng của bạn. Tôi nghi ngờ rằng đọc trong các tập tin csv của kích thước bạn đang nói về sẽ không quan trọng về tốc độ so với PyTables. Nhưng nếu đó là một mối quan tâm, hãy viết một điểm chuẩn! Đọc và ghi một số dữ liệu ngẫu nhiên 100 lần. Hoặc, nếu thời gian đọc quan trọng hơn, hãy viết một lần, đọc 100 lần, v.v.

Tôi nghi ngờ rằng PyTables sẽ hoạt động tốt hơn SQL. SQL sẽ đá trên các truy vấn phức tạp nhiều bảng (đặc biệt là nếu bạn làm những điều tương tự thường xuyên), nhưng ngay cả trên bảng đơn (được gọi là "không chuẩn hóa") bảng, pytables là khó để đánh bại về tốc độ. Tôi không thể tìm thấy một tài liệu tham khảo cho việc này off-hand, nhưng bạn có thể đào một cái gì đó lên nếu bạn khai thác các liên kết ở đây:

http://www.pytables.org/moin/HowToUse#HintsforSQLusers

Tôi đoán thực hiện hiệu suất cho bạn trong giai đoạn này sẽ nhợt nhạt so với hiệu suất của coder. Vì vậy, trên hết, hãy chọn thứ gì đó có ý nghĩa nhất đối với bạn!

Các điểm khác:

Giống như với SQL, PyTables có tính năng hoàn tác. Tệp CSV sẽ không có điều này, nhưng bạn có thể giữ chúng trong điều khiển phiên bản và bạn VCS không cần phải quá thông minh (tệp CSV là văn bản).

Trên ghi chú liên quan, tệp CSV sẽ lớn hơn nhiều so với định dạng nhị phân (bạn chắc chắn có thể viết các bài kiểm tra của riêng mình cho quá này).

2

Một điểm cộng lớn cho PyTables là lưu trữ siêu dữ liệu, như biến, v.v. Nếu bạn chạy mô phỏng thường xuyên hơn với các thông số khác nhau, bạn lưu kết quả dưới dạng mục nhập mảng trong tệp h5.

Chúng tôi sử dụng nó để lưu trữ dữ liệu đo lường + tập lệnh thử nghiệm để lấy dữ liệu để dữ liệu được tự chứa.

BTW: Nếu bạn cần xem nhanh tệp hdf5, bạn có thể sử dụng HDFView. Đó là một ứng dụng Java miễn phí từ HDFGroup. Thật dễ dàng để cài đặt.

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