在文件中保存数组或数据帧以及其他信息

2024-04-26 17:17:07 发布

您现在位置:Python中文网/ 问答频道 /正文

统计软件Stata允许将短文本片段保存在数据集中。这可以使用^{}和/或^{}来完成。

这是一个对我很有价值的特性,因为它允许我保存各种信息,从提醒和待办事项列表到关于我如何生成数据的信息,甚至是特定变量的估计方法。

我现在正试图在Python3.6中开发类似的功能。到目前为止,我已经在网上查阅了一些帖子,但这些帖子并不能完全说明我想做什么。

一些参考职位包括:

对于一个小的NumPy数组,我的结论是函数^{}dictionary的组合可以在一个文件中充分存储所有相关信息。

例如:

a = np.array([[2,4],[6,8],[10,12]])
d = {"first": 1, "second": "two", "third": 3}

np.savez(whatever_name.npz, a=a, d=d)
data = np.load(whatever_name.npz)

arr = data['a']
dic = data['d'].tolist()

然而,问题仍然是:

在包含NumPy数组或(大的)PandasDataFrame的文件中是否有更好的方法潜在地合并其他信息?

我特别感兴趣的是,你可以通过例子来听听你的建议中的特别的优点和缺点。依赖关系越少越好。


Tags: csvtheto数据方法信息pandasdata
3条回答

有很多选择。我只讨论HDF5,因为我有使用这种格式的经验。

优点:可移植(可在Python外部读取)、本机压缩、内存不足功能、元数据支持。

缺点:依赖于单个低级C API,单个文件存在数据损坏的可能性,删除数据不会自动减小大小。

以我的经验,为了性能和可移植性,避免存储数字数据。您可以使用^{}提供的直观界面。

存储数组

import h5py, numpy as np

arr = np.random.randint(0, 10, (1000, 1000))

f = h5py.File('file.h5', 'w', libver='latest')  # use 'latest' for performance

dset = f.create_dataset('array', shape=(1000, 1000), data=arr, chunks=(100, 100),
                        compression='gzip', compression_opts=9)

压缩和分块

有许多压缩选择,例如blosclzf分别是压缩和解压缩性能的好选择。注意gzip是本机的;其他压缩过滤器在默认情况下可能不会随HDF5安装一起提供。

分块是另一个选项,当它与从内存中读取数据的方式一致时,可以显著提高性能。

添加一些属性

dset.attrs['Description'] = 'Some text snippet'
dset.attrs['RowIndexArray'] = np.arange(1000)

存储字典

for k, v in d.items():
    f.create_dataset('dictgroup/'+str(k), data=v)

内存不足访问

dictionary = f['dictgroup']
res = dictionary['my_key']

阅读h5pydocumentation是无可替代的,它公开了大部分C API,但是您应该从上面看到它有很大的灵活性。

我同意JPP的说法,hdf5存储是一个不错的选择。他的解决方案与我的不同之处在于,我的解决方案使用Pandas数据帧,而不是numpy数组。我更喜欢dataframe,因为它允许混合类型、多级索引(甚至对我的工作非常重要的datetime索引)和列标记,这有助于我记住不同数据集是如何组织的。此外,Pandas还提供了许多内置功能(非常像numpy)。使用Pandas的另一个好处是它内置了一个hdf创建者(即Pandas.DataFrame.to-hdf),我觉得这很方便

在将数据帧存储到h5时,您还可以选择存储元数据字典,它可以是您自己的注释,也可以是不需要存储在数据帧中的实际元数据(我也使用它来设置标志,例如{'is-agl':True,'scale-factor':100,'already-corrected':False等等)。在这方面,使用numpy数组和数据帧没有区别。有关完整的解决方案,请参见my original question and solution here.

一种实用的方法是将元数据直接嵌入到Numpy数组中。优点是,正如您所希望的,没有额外的依赖性,而且在代码中使用非常简单。 但是,这并不能完全回答您的问题,因为您仍然需要一种保存数据的机制,我建议您使用使用HDF5的jpp解决方案。

要在ndarray中包含元数据,在the documentation中有一个示例。 基本上,你必须对一个ndarray进行子类划分,并添加一个字段infometadata或其他什么。

它会给出(上面链接的代码)

import numpy as np

class ArrayWithInfo(np.ndarray):

    def __new__(cls, input_array, info=None):
        # Input array is an already formed ndarray instance
        # We first cast to be our class type
        obj = np.asarray(input_array).view(cls)
        # add the new attribute to the created instance
        obj.info = info
        # Finally, we must return the newly created object:
        return obj

    def __array_finalize__(self, obj):
        # see InfoArray.__array_finalize__ for comments
        if obj is None: return
        self.info = getattr(obj, 'info', None)

要通过numpy保存数据,需要重载write函数或使用其他解决方案。

相关问题 更多 >