统计软件Stata允许将短文本片段保存在数据集中。这可以使用notes
和/或characteristics
完成。
这对我来说是一个很有价值的功能,因为它允许我保存各种信息,从提醒和待办事项列表到有关我如何生成数据的信息,甚至是特定变量的估算方法是。
我现在正试图在Python 3.6中提出类似的功能。到目前为止,我已经在线查看了一些帖子,但这些帖子并没有完全解决我想做的事情。
一些参考文章包括:
What is the difference between save a pandas dataframe to pickle and to csv?
What is the fastest way to upload a big csv file in notebook to work with python pandas?
对于较小的NumPy
数组,我得出结论,函数numpy.savez()
和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
数组或(大)Pandas
DataFrame
的文件中?
我特别感兴趣的是,您可以通过示例了解任何建议的专业和缺点。依赖性越少越好。
答案 0 :(得分:19)
有很多选择。我将只讨论HDF5,因为我有使用这种格式的经验。
优点:可移植(可在Python之外读取),本机压缩,内存不足功能,元数据支持。
缺点:依赖单个低级别C API,将数据损坏作为单个文件的可能性,删除数据不会自动减小大小。
根据我的经验,出于性能和可移植性,避免 pyTables
/ HDFStore
来存储数字数据。您可以使用h5py
提供的直观界面。
存储数组
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)
压缩&分块强>
有许多压缩选择,例如blosc
和lzf
分别是压缩和解压缩性能的不错选择。注意gzip
是原生的;默认情况下,您的HDF5安装可能无法提供其他压缩过滤器。
Chunking是另一种选择,当与读取数据内存时的方式一致时,可以显着提高性能。
添加一些属性
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']
没有任何替代方法可以阅读h5py
documentation,这会暴露大部分C API,但您应该从上面看到它具有很大的灵活性。
答案 1 :(得分:7)
我同意JPP的说法,hdf5存储在这里是个不错的选择。他和我的解决方案之间的区别在于我使用Pandas数据帧而不是numpy数组。我更喜欢数据框,因为它允许混合类型,多级索引(甚至是日期时间索引,这对我的工作非常重要),以及列标记,这有助于我记住不同数据集的组织方式。此外,熊猫提供了一系列内置功能(非常像numpy)。使用Pandas的另一个好处是它内置了一个hdf创建器(即pandas.DataFrame.to_hdf),我觉得很方便
当将数据帧存储到h5时,您可以选择存储元数据字典,这可以是您自己的注释,也可以是不需要存储在数据帧中的实际元数据(我用它来设置标志)同样,例如{' is_agl':True,' scale_factor':100,'已经校正':False,等等}。在这方面,没有区别在使用numpy数组和数据帧之间。有关完整解决方案,请参阅my original question and solution here.
答案 2 :(得分:4)
实用的方法是将元数据直接嵌入Numpy数组中。优点是,正如您所希望的那样,没有额外的依赖性,并且在代码中使用起来非常简单。 但是,这并不能完全回答您的问题,因为您仍需要一种机制来保存数据,我建议您使用HDF5使用jpp的解决方案。
要在ndarray
中包含元数据,the documentation中有一个示例。
您基本上必须继承ndarray
并添加字段info
或metadata
或其他任何内容。
它会给出(来自上面链接的代码)
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
功能或使用其他解决方案。
答案 3 :(得分:3)
jpp的答案非常全面,只是想提一下,因为pandas v22实木复合地板是非常方便快捷的选择,与csv几乎没有任何弊端(也许接受咖啡休息)。
在撰写本文时,您还需要
pip install pyarrow
在添加信息方面,您拥有附加到数据的元数据
import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.normal(size=(1000, 10)))
tab = pa.Table.from_pandas(df)
tab = tab.replace_schema_metadata({'here' : 'it is'})
pq.write_table(tab, 'where_is_it.parq')
pq.read_table('where_is_it.parq')
Pyarrow table
0: double
1: double
2: double
3: double
4: double
5: double
6: double
7: double
8: double
9: double
__index_level_0__: int64
metadata
--------
{b'here': b'it is'}
要把它带回熊猫:
tab.to_pandas()
答案 4 :(得分:-1)
这是一个有趣的问题,尽管我认为这是非常开放的。
文字摘要
对于包含文字注释的文本片段(如,不是代码而不是数据),我真的不知道你的用例是什么,但我不知道为什么我会偏离使用通常的{{ 1}}
各种数据的小集合
当然,你的with open() as f: ...
有效。实际上你正在做的非常类似于创建一个字典,其中包含你要保存的所有东西并且用这个字典腌制它。
有关pickle和npz之间差异的讨论,请参阅here(但主要是npz针对numpy数组进行了优化)。
就个人而言,我说如果你不存储Numpy数组我会使用pickle,甚至实现一个快速npz
类,它基本上是一个字典来保存其中的东西,还有一些额外的功能你可能想要。
大型物品的集合
对于我在HDF5格式之前使用的非常大的np.arrays或数据帧。好处是它已经内置到大熊猫中,你可以直接df.to_hdf5()
。它确实需要在MyNotes
下面 - 安装应该是相当轻松的pip或conda-但直接使用pytables可能是一个更大的痛苦。
同样,这个想法非常相似:你正在创建一个HDFStore,它几乎是一个可以存储(几乎任何)对象的大字典。好处是该格式通过利用类似值的重复以更智能的方式利用空间。当我用它来存储大约2GB的数据帧时,它能够将它减少几乎整整的数量级(~250MB)。
最后一位玩家:pytables
Feather
是由Wes McKinney和Hadley Wickham在Apache Arrow框架之上创建的项目,用于以与语言无关的二进制格式保存数据(因此您可以从R和Python中读取)。但是,它仍在开发中,上次我检查时他们并不鼓励将其用于长期存储(因为规范可能会在未来的版本中更改),而不是仅仅用于R和Python之间的通信
他们刚刚在几周前推出了Ursalabs,这将继续发展这一举措和类似举措。
答案 5 :(得分:-1)
你说这个问题的原因是:
...它允许我 保存 各种信息,从提醒和待办事项列表,到 有关我如何生成数据的信息,甚至是什么 特定变量的估算方法是 。
我可以建议一个与Stata提供的范式不同的范例吗?笔记和特征似乎非常有限,仅限于文本。相反,您应该使用Jupyter Notebook进行研究和数据分析项目。它提供了如此丰富的环境来记录您的工作流程,并在您进行分析和研究时捕获细节,想法和想法。它可以很容易地共享,并且可以进行演示。
以下是许多行业和学科的a gallery of interesting Jupyter Notebooks,以展示笔记本电脑的众多功能和用例。它可能会扩展您的视野,而不是试图设计一种方法来将简单的文本片段标记为您的数据。