【发布时间】:2015-05-21 15:39:52
【问题描述】:
我记得在我使用结构化数组的 MatLab 日子里,您可以将不同的数据存储为主要结构的属性。比如:
a = {}
a.A = magic(10)
a.B = magic(50); etc.
其中a.A 和a.B 彼此完全分开,允许您在a 中存储不同的类型并根据需要对其进行操作。 Pandas 允许我们做类似的事情,但并不完全相同。
我正在使用 Pandas 并希望存储数据帧的属性,而不是将其实际放入数据帧中。这可以通过以下方式完成:
import pandas as pd
a = pd.DataFrame(data=pd.np.random.randint(0,100,(10,5)),columns=list('ABCED')
# now store an attribute of <a>
a.local_tz = 'US/Eastern'
现在,本地时区存储在 a 中,但我在保存数据帧时无法保存此属性(即重新加载 a 后没有 a.local_tz)。有没有办法保存这些属性?
目前,我只是在数据框中创建新列来保存时区、纬度、经度等信息,但这似乎有点浪费。此外,当我对数据进行分析时,我遇到了必须排除这些其他列的问题。
################## 开始编辑 ##################
根据 unutbu 的建议,我现在以 h5 格式存储数据。如前所述,将元数据作为数据框的属性重新加载是有风险的。但是,由于我是这些文件(和处理算法)的创建者,我可以选择哪些存储为元数据,哪些不存储。在处理将进入 h5 文件的数据时,我选择将元数据存储在一个字典中,该字典被初始化为我的类的属性。我做了一个简单的 IO 类来导入 h5 数据,并将元数据作为类属性。现在我可以处理我的数据帧,而不会丢失元数据。
class IO():
def __init__(self):
self.dtfrmt = 'dummy_str'
def h5load(self,filename,update=False):
'''h5load loads the stored HDF5 file. Both the dataframe (actual data) and
the associated metadata are stored in the H5file
NOTE: This does not load "any" H5
file, it loads H5 files specifically created to hold dataframe data and
metadata.
When multi-indexed dataframes are stored in the H5 format the date
values (previously initialized with timezone information) lose their
timezone localization. Therefore, <h5load> re-localizes the 'DATE'
index as UTC.
Parameters
----------
filename : string/path
path and filename of H5 file to be loaded. H5 file must have been
created using <h5store> below.
udatedf : boolean True/False
default: False
If the selected dataframe is to be updated then it is imported
slightly different. If update==True, the <metadata> attribute is
returned as a dictionary and <data> is returned as a dataframe
(i.e., as a stand-alone dictionary with no attributes, and NOT an
instance of the IO() class). Otherwise, if False, <metadata> is
returned as an attribute of the class instance.
Output
------
data : Pandas dataframe with attributes
The dataframe contains only the data as collected by the instrument.
Any metadata (e.g. timezone, scaling factor, basically anything that
is constant throughout the file) is stored as an attribute (e.g. lat
is stored as <data.lat>).'''
with pd.HDFStore(filename,'r') as store:
self.data = store['mydata']
self.metadata = store.get_storer('mydata').attrs.metadata # metadata gets stored as attributes, so no need to make <metadata> an attribute of <self>
# put metadata into <data> dataframe as attributes
for r in self.metadata:
setattr(self,r,self.metadata[r])
# unscale data
self.data, self.metadata = unscale(self.data,self.metadata,stringcols=['routine','date'])
# when pandas stores multi-index dataframes as H5 files the timezone
# initialization is lost. Remake index with timezone initialized: only
# for multi-indexed dataframes
if isinstance(self.data.index,pd.core.index.MultiIndex):
# list index-level names, and identify 'DATE' level
namen = self.data.index.names
date_lev = namen.index('DATE')
# extract index as list and remake tuples with timezone initialized
new_index = pd.MultiIndex.tolist(self.data.index)
for r in xrange( len(new_index) ):
tmp = list( new_index[r] )
tmp[date_lev] = utc.localize( tmp[date_lev] )
new_index[r] = tuple(tmp)
# reset multi-index
self.data.index = pd.MultiIndex.from_tuples( new_index, names=namen )
if update:
return self.metadata, self.data
else:
return self
def h5store(self,data, filename, **kwargs):
'''h5store stores the dataframe as an HDF5 file. Both the dataframe
(actual data) and the associated metadata are stored in the H5file
Parameters
----------
data : Pandas dataframe NOT a class instance
Must be a dataframe, not a class instance (i.e. cannot be an instance
named <data> that has an attribute named <data> (e.g. the Pandas
data frame is stored in data.data)). If the dataframe is under
data.data then the input variable must be data.data.
filename : string/path
path and filename of H5 file to be loaded. H5 file must have been
created using <h5store> below.
**kwargs : dictionary
dictionary containing metadata information.
Output
------
None: only saves data to file'''
with pd.HDFStore(filename,'w') as store:
store.put('mydata',data)
store.get_storer('mydata').attrs.metadata = kwargs
然后通过data = IO().h5load('filename.h5') 加载H5 文件
数据框存储在 data.data 下
我将元数据字典保留在 data.metadata 下,并创建了单独的元数据属性(例如 data.lat 创建自 data.metadata['lat'])。
我的索引时间戳本地化为pytz.utc()。但是,当多索引数据帧存储到 h5 时,时区定位会丢失(使用 Pandas 15.2),所以我在 IO().h5load 中对此进行了更正。
【问题讨论】:
-
虽然属性可以添加到 df 中,但它们不会被复制,即使你做了
df.copy()所以你必须使用另一种方法来存储它
标签: python-2.7 pandas