我正在处理大型3D阵列,我经常需要以各种方式进行切片以进行各种数据分析.典型的"立方体"可以是~100GB(将来可能会变大)
似乎python中大型数据集的典型推荐文件格式是使用HDF5(h5py或pytables).我的问题是:使用HDF5存储和分析这些立方体而不是将它们存储在简单的平面二进制文件中是否有任何速度或内存使用效益?HDF5是否更适合表格数据,而不像我正在使用的大型数组?我看到HDF5可以提供很好的压缩,但我对处理速度和处理内存溢出更感兴趣.
我经常只想分析立方体的一个大的子集.pytables和h5py的一个缺点是,当我拿一个数组时,我总是得到一个numpy数组,用尽内存.但是,如果我切片平面二进制文件的numpy memmap,我可以得到一个视图,它将数据保存在磁盘上.因此,似乎我可以更轻松地分析我的数据的特定部分而不会超出我的记忆.
我已经探讨了pytables和h5py,到目前为止还没有看到我的目的的好处.
我已经使用大熊猫进行研究了大约两个月,效果很好.有了大量的中型跟踪事件数据集,pandas + PyTables(HDF5接口)在允许我使用我所熟悉和喜爱的所有Python工具处理异构数据方面做了大量工作.
一般来说,我在PyTables中使用Fixed(以前称为"Storer")格式,因为我的工作流程是一次写入,多次读取,并且我的许多数据集的大小都是这样的,我可以将50-100个数据集加载到内存中.时间没有严重的缺点.(注意:我的大部分工作都是在具有128GB +系统内存的Opteron服务器级机器上完成的.)
但是,对于大型数据集(500MB或更高),我希望能够使用PyTables"Tables"格式的更具可伸缩性的随机访问和查询功能,这样我就可以在内存之外执行查询,然后将更小的结果集加载到内存中进行处理.然而,这里的一大障碍是写性能.是的,正如我所说,我的工作流程是一次写入,多次读取,但相对时间仍然是不可接受的.
作为一个例子,我最近在我的48核心机器上运行了一个大型的Cholesky分解,花了3分8秒(188秒).这会生成~2.2 GB的跟踪文件 - 跟踪与程序并行生成,因此没有额外的"跟踪创建时间".
我的二进制跟踪文件初始转换为pandas/PyTables格式花费了相当多的时间,但很大程度上是因为二进制格式是故意无序的,以减少跟踪生成器本身的性能影响.这与从Storer格式转换为Table格式时的性能损失无关.
我的测试最初是用pandas 0.12,numpy 1.7.1,PyTables 2.4.0和numexpr 0.20.1运行的.我的48核心机器每个核心运行2.8GHz,我正在写一个ext3文件系统,它可能(但不一定)在SSD上.
我可以在7.1秒内将整个数据集写入Storer格式的HDF5文件(生成文件大小:3.3GB).写入表格式的相同数据集(结果文件大小也是3.3GB),写入需要178.7秒.
代码如下:
with Timer() as t:
store = pd.HDFStore('test_storer.h5', 'w')
store.put('events', events_dataset, table=False, append=False)
print('Fixed format write took ' + str(t.interval))
with Timer() as t:
store = pd.HDFStore('test_table.h5', 'w')
store.put('events', events_dataset, table=True, append=False)
print('Table format write took ' + str(t.interval))
Run Code Online (Sandbox Code Playgroud)
输出很简单
Fixed format write took 7.1
Table format write took 178.7
Run Code Online (Sandbox Code Playgroud)
我的数据集有28,880,943行,列是基本数据类型:
node_id int64
thread_id int64
handle_id int64
type int64
begin int64
end int64 …
Run Code Online (Sandbox Code Playgroud) 请考虑以下示例:
import string
import random
import pandas as pd
matrix = np.random.random((100, 3000))
my_cols = [random.choice(string.ascii_uppercase) for x in range(matrix.shape[1])]
mydf = pd.DataFrame(matrix, columns=my_cols)
mydf['something'] = 'hello_world'
Run Code Online (Sandbox Code Playgroud)
store = pd.HDFStore('myfile.h5',complevel=9, complib='bzip2')
store['mydf'] = mydf
store.close()
Run Code Online (Sandbox Code Playgroud)
mydf.to_csv('myfile.csv', sep=':')
Run Code Online (Sandbox Code Playgroud)
结果是:
myfile.csv
是5.6 MB大myfile.h5
是11 MB大随着数据集变大,差异越来越大.
我尝试过其他压缩方法和级别.这是一个错误吗?(我正在使用Pandas 0.11和HDF5和Python的最新稳定版本).
import pandas as pd
df = pd.DataFrame({'a' : [1,2,3]})
df.to_hdf('temp.h5', key='df', mode='w')
Run Code Online (Sandbox Code Playgroud)
这给了我错误。
缺少可选的依赖“表”。使用 pip 或 conda 安装表。
我已经尝试过 ImportError HDFStore requires PyTables No module named tables。还是一样的错误。
读取 hdf 文件时出现相同的错误。并且tables
已经为我的python安装了。
一些版本信息。
- 蟒蛇 3.7.4
- 熊猫 0.25.2
- 视窗10
PS:您可以在repl
https://repl.it/ 中重现此内容。
更新:
import tables
Run Code Online (Sandbox Code Playgroud)
并收到此错误:
导入错误:无法加载任何 ['hdf5.dll'、'hdf5dll.dll'],请确保它可以在系统路径中找到。
看起来熊猫没有为此提供准确的信息。它只是在实际存在时说缺少依赖项。
如果有人知道如何解决这个问题。那会有所帮助。
我有一个100M行csv文件(实际上很多单独的csv文件)总共84GB.我需要将它转换为具有单个float数据集的HDF5文件.我在测试中使用了h5py而没有任何问题,但是现在我不能在没有内存耗尽的情况下完成最终的数据集.
如何在不必将整个数据集存储在内存中的情况下写入HDF5?我在这里期待实际代码,因为它应该非常简单.
我只是在研究pytables,但它看起来不像数组类(对应于HDF5数据集)可以迭代编写.同样,熊猫拥有read_csv
和to_hdf
在它的方法io_tools
,但我不能在同一时间加载整个数据集,这样将无法正常工作.也许你可以帮我用pytables或pandas中的其他工具正确解决问题.
让Python和Java相互配合的最佳方法是什么?
我有点复杂的情况.我会尽力用图片和文字来解释.这是当前的系统架构:
当前的系统架构http://i50.tinypic.com/2s6lutk.png
我们有一个用Java编写的基于代理的建模仿真.它可以选择本地写入CSV文件,也可以通过与Java服务器的连接远程写入HDF5文件.每次模拟运行超过一千兆字节的数据,我们运行模拟数十次.我们需要能够聚合同一场景的多次运行(使用不同的随机种子)以查看一些趋势(例如,min,max,median,mean).可以想象,试图移动所有这些CSV文件是一场噩梦; 每次运行都会生成多个文件,就像我说的一些文件非常庞大.这就是我们一直试图转向HDF5解决方案的原因,其中研究的所有数据都存储在一个地方,而不是分散在几十个纯文本文件中.此外,由于它是二进制文件格式,与未压缩的CSVS相比,它应该能够节省大量空间.
如图所示,我们对来自仿真的原始输出数据进行的当前后处理也在Java中进行,并读取由本地输出生成的CSV文件.此后处理模块使用JFreeChart创建与模拟相关的一些图表和图形.
正如我前面提到的,当我们从模拟中生成越来越多的数据时,CSV实际上是站不住脚的,并且不能很好地扩展.此外,后处理代码所做的工作比它本来应该做的更多,基本上执行非常非常差的人的关系数据库的工作(基于外键(唯一的代理ID)在'表'(csv文件)之间进行连接在该系统中,以其他方式可视化数据也很困难(例如,Prefuse,Processing,JMonkeyEngine获取MatLab或SPSS中的一些原始数据子集).
我的小组决定我们真的需要一种过滤和查询我们拥有的数据的方法,以及执行跨表连接.鉴于这是一次写入,多次读取的情况,我们真的不需要真正的关系数据库的开销; 相反,我们只需要一些方法在HDF5文件上放置一个更好的前端.我发现了一些关于此的论文,比如描述如何使用XQuery作为HDF5文件的查询语言,但是本文描述了编写一个编译器以将XQuery/XPath转换为本机HDF5调用,超出了我们的需要.输入PyTables.它似乎正是我们所需要的(提供两种不同的查询数据的方式,通过Python列表理解或通过内核(C级)搜索.
我设想的建议架构是: Envisioned architecture http://i46.tinypic.com/9aseg3.png
我不确定该怎么做的是将用于查询的python代码与提供HDF5文件的Java代码以及执行数据后处理的Java代码链接在一起.显然,我会想要重写大部分隐式执行查询的后处理代码,而是让优秀的PyTables更优雅地完成这项工作.
一个简单的谷歌搜索为Java和Python之间的通信提供了一些选择,但我对这个主题是如此新颖,我正在寻找一些实际的专业知识和批评建议的架构.看起来Python进程应该与Datahose在同一台机器上运行,这样大的.h5文件就不必通过网络传输,而是将它的小得多的过滤视图传输给客户端. Pyro似乎是一个有趣的选择 - 有没有人有这方面的经验?
大熊猫对如何存储下面的例子Series
,DataFrames
并Panels
在HDF5文件:
In [1142]: store = HDFStore('store.h5')
In [1143]: index = date_range('1/1/2000', periods=8)
In [1144]: s = Series(randn(5), index=['a', 'b', 'c', 'd', 'e'])
In [1145]: df = DataFrame(randn(8, 3), index=index,
......: columns=['A', 'B', 'C'])
......:
In [1146]: wp = Panel(randn(2, 5, 4), items=['Item1', 'Item2'],
......: major_axis=date_range('1/1/2000', periods=5),
......: minor_axis=['A', 'B', 'C', 'D'])
......:
Run Code Online (Sandbox Code Playgroud)
In [1147]: store['s'] = s
In [1148]: store['df'] = df
In [1149]: store['wp'] = wp
Run Code Online (Sandbox Code Playgroud)
In [1150]: store …
Run Code Online (Sandbox Code Playgroud) 我在使用PyTables存储numpy csr_matrix时遇到问题.我收到这个错误:
TypeError: objects of type ``csr_matrix`` are not supported in this context, sorry; supported objects are: NumPy array, record or scalar; homogeneous list or tuple, integer, float, complex or string
Run Code Online (Sandbox Code Playgroud)
我的代码:
f = tables.openFile(path,'w')
atom = tables.Atom.from_dtype(self.count_vector.dtype)
ds = f.createCArray(f.root, 'count', atom, self.count_vector.shape)
ds[:] = self.count_vector
f.close()
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
谢谢
我有大约700万行,HDFStore
超过60列.数据超出了我的记忆能力.我希望根据列"A"的值将数据聚合成组.pandas 拆分/聚合/组合的文档假定我已经拥有了所有数据DataFrame
,但是我无法将整个存储读入内存中DataFrame
.将数据分组的正确方法是HDFStore
什么?
如何使用PyTables将numpy多维数组放入HDF5文件中?
据我所知,我不能在pytables表中放置一个数组字段.
我还需要存储有关此数组的一些信息,并能够对其进行数学计算.
有什么建议?