Pytables 与 CSV 在小文件中的对比

8 投票
6 回答
3524 浏览
提问于 2025-04-16 06:06

我最近发现了Pytables,觉得它非常酷。显然,对于非常大的数据集,它比csv格式要好很多。我正在用python进行一些模拟,输出的数据并不是很大,大概有200列和2000行。

如果有人对这两者都有经验,能不能建议一下,对于这种不算太大的数据集,哪种格式在长远来看更方便?Pytables有数据处理的功能,还可以用Vitables浏览数据,但这个浏览器的功能没有Excel那么强大,而Excel可以用来处理CSV文件。同样的,如果主要在python中工作,你觉得在导入和导出数据方面,哪种更好?在文件组织方面,有没有哪种更方便?对这些问题的任何评论都会很有帮助。

谢谢。

6 个回答

2

PyTables 有一个很大的优点,就是可以存储一些额外的信息,比如变量等等。如果你经常用不同的参数来运行模拟,你可以把结果存储为 h5 文件中的一个数组项。

我们用它来存储测量数据和实验脚本,这样所有的数据都是自给自足的。

顺便提一下,如果你想快速查看一个 hdf5 文件,可以使用 HDFView。这是一个免费的 Java 应用程序,来自 HDFGroup,安装起来也很简单。

2

在导入和导出数据方面,PyTables使用了一种标准的文件格式,叫做HDF5。很多科学软件,比如MATLAB,都内置支持HDF5格式,而且它的C语言接口也还不错。所以,如果你需要从这些语言中导入或导出数据,可以直接把数据保存在HDF5文件里。

PyTables确实会添加一些自己的属性,但这些不会对你造成困扰。当然,如果你把Python对象存储在文件里,就无法在其他地方读取它们了。

CSV文件有一个好处,就是人能看懂。不过,如果你需要存储简单数字以外的东西,并且还要和别人交流,就会遇到问题。我从其他组织的人那里收到CSV文件,发现人们在确保字符串引号等格式正确方面做得并不好。幸好Python的CSV解析器很灵活。还有一个问题是,浮点数在文本中用十进制格式存储时不能完全准确。不过通常来说,这样的精度已经足够了。

6

你有没有考虑过使用Numpy数组呢?

当你的数据太大,无法全部放进内存时,PyTables是个很好的选择。不过,一个200行乘以2000列的矩阵,里面存的是8字节的浮点数,实际上只需要大约3MB的内存。所以我觉得用PyTables可能有点过于复杂了。

你可以使用np.savetxt或者np.savez(可以压缩文件)把Numpy数组保存到文件里,然后用np.loadtxt或者np.load从文件中读取它们。

如果你有很多这样的数组需要存储在磁盘上,我建议你使用数据库,而不是Numpy的.npz文件。顺便说一下,要在数据库中存储一个200x2000的矩阵,你只需要3个表格列:行、列和数值:

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.80123759  0.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.80123759  0.52689885  0.05861043  0.71784406  0.20222138  0.63094807]
#  [ 0.01309897  0.45391578  0.04950273  0.93040381  0.41150517  0.66263562]]

如果你有很多这样的200x2000矩阵,你只需要再多一个表格列来指定是哪一个矩阵。

撰写回答