2015-03-18 33 views
9

में अतिरिक्त विशेषताओं को सहेजें I संरचित सरणी का उपयोग करके मेरे मैटलैब दिनों से याद करते हैं जिसमें आप मुख्य संरचना की विशेषता के रूप में विभिन्न डेटा स्टोर कर सकते हैं। की तरह कुछ:पांडस डेटाफ्रेम

a = {} 
a.A = magic(10) 
a.B = magic(50); etc. 

जहां a.A और a.b आप एक के भीतर विभिन्न प्रकार की दुकान और के रूप में वांछित उन पर संचालित करने के लिए अनुमति देता है एक दूसरे से बिल्कुल अलग होती हैं। पांडस हमें कुछ ऐसा करने की इजाजत देता है, लेकिन काफी समान नहीं है।

मैं पांडा उपयोग कर रहा हूँ और वास्तव में यह एक dataframe भीतर डाले बिना एक dataframe की विशेषताओं संग्रहीत करना चाहते हैं।

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' 

अब, स्थानीय समय क्षेत्र एक में संग्रहित है, लेकिन जब मैं dataframe बचाने मैं यह विशेषता नहीं बचा सकता है (यानी एक फिर से लोड करने के बाद वहाँ कोई a.local_tz है): के माध्यम से यह किया जा सकता है। क्या इन गुणों को सहेजने का कोई तरीका है?

वर्तमान में, मैं सिर्फ नए कॉलम dataframe समय क्षेत्र, अक्षांश, longituded, आदि जैसे जानकारी धारण करने के लिए में बनाने रहा हूँ, लेकिन इस बर्बादी का एक सा हो रहा है। इसके अलावा, जब मैं डेटा पर विश्लेषण करता हूं तो मैं इन अन्य कॉलम को बाहर करने की समस्याओं में भाग लेता हूं।

################## संपादित शुरू ##################

unutbu के का उपयोग करना सलाह, अब मैं डेटा को एच 5 प्रारूप में संग्रहीत करता हूं। जैसा कि बताया गया है, डेटाफ्रेम के गुणों के रूप में वापस मेटाडेटा लोड करना खतरनाक है। हालांकि, चूंकि मैं इन फ़ाइलों (और प्रसंस्करण एल्गोरिदम) का निर्माता हूं, इसलिए मैं मेटाडेटा के रूप में संग्रहीत किया जा सकता हूं और क्या नहीं है। डेटा को संसाधित करते समय जो एच 5 फाइलों में जाएगा, मैं मेटाडेटा को उस शब्दकोश में संग्रहीत करना चुनता हूं जो मेरी कक्षाओं की विशेषता के रूप में प्रारंभ होता है। मैंने एच 5 डेटा आयात करने के लिए एक सरल आईओ कक्षा बनाई, और मेटाडेटा को वर्ग विशेषताओं के रूप में बनाया। अब मैं मेटाडेटा खोने के जोखिम के बिना अपने डेटाफ्रेम पर काम कर सकता हूं।

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 

H5 फ़ाइलों तो डेटा के माध्यम से लोड किए गए हैं = आईओ()। H5load ('filename.h5') dataframe data.data मैं data.metadata तहत मेटाडाटा शब्दकोश को बनाए रखने और अलग-अलग बनाया है के तहत संग्रहीत किया जाता है मेटाडाटा विशेषताएँ (उदाहरण के लिए data.lad डेटा.मैटडाटा ['lat'] से बनाई गई)।

मेरे सूचकांक समय टिकटों pytz.utc को स्थानीयकृत हैं()। हालांकि, जब एक बहु-अनुक्रमित डेटाफ्रेम एच 5 में संग्रहीत किया जाता है तो टाइमज़ोन स्थानीयकरण खो जाता है (पांडस 15.2 का उपयोग करके), इसलिए मैं इसके लिए IO()। H5load में सही करता हूं।

+1

हालांकि गुण एक df वे कॉपी नहीं किया जाएगा करने के लिए जोड़ा जा सकता है, भले ही आप 'किया df.copy()' आप चाहते हैं तो इसे किसी अन्य विधि का उपयोग करके स्टोर करने के लिए – EdChum

उत्तर

20

There is an open issue NDFrames में कस्टम मेटाडाटा के भंडारण के बारे में। लेकिन बहुसंख्यक तरीकों के कारण पांडा कार्य डेटाफ्रेम वापस कर सकते हैं, _metadata विशेषता सभी परिस्थितियों में संरक्षित नहीं है (अभी तक)।

कुछ समय के लिए, तो आप सिर्फ एक सहायक चर में मेटाडाटा स्टोर करने के लिए होगा। अचार, JSON, HDF5 सभी संभावनाओं कर रहे हैं -

फ़ाइलों को DataFrames + मेटाडाटा भंडारण, आप उपयोग करना चाहते क्या प्रारूप के आधार पर के लिए कई विकल्प हैं।

यहां बताया गया है कि आप एचडीएफ 5 का उपयोग करके मेटाडेटा के साथ डेटाफ्रेम को कैसे स्टोर और लोड कर सकते हैं। मेटाडेटा को संग्रहीत करने के लिए नुस्खा Pandas Cookbook से आता है।

import numpy as np 
import pandas as pd 

def h5store(filename, df, **kwargs): 
    store = pd.HDFStore(filename) 
    store.put('mydata', df) 
    store.get_storer('mydata').attrs.metadata = kwargs 
    store.close() 

def h5load(store): 
    data = store['mydata'] 
    metadata = store.get_storer('mydata').attrs.metadata 
    return data, metadata 

a = pd.DataFrame(
    data=pd.np.random.randint(0, 100, (10, 5)), columns=list('ABCED')) 

filename = '/tmp/data.h5' 
metadata = dict(local_tz='US/Eastern') 
h5store(filename, a, **metadata) 
with pd.HDFStore(filename) as store: 
    data, metadata = h5load(store) 

print(data) 
#  A B C E D 
# 0 9 20 92 43 25 
# 1 2 64 54 0 63 
# 2 22 42 3 83 81 
# 3 3 71 17 64 53 
# 4 52 10 41 22 43 
# 5 48 85 96 72 88 
# 6 10 47 2 10 78 
# 7 30 80 3 59 16 
# 8 13 52 98 79 65 
# 9 6 93 55 40 3 

print(metadata) 

पैदावार

{'local_tz': 'US/Eastern'} 
+0

बढ़िया! दरअसल, जब मैं मेटाडाटा में आर के लिए H5file लोड करता हूं: : setattr (डेटा, आर, मेटाडाटा [आर]) – tnknepp

+0

यह मुझे काफी लचीला और बिल्कुल वही बनाता है जो मैं चाहता हूं कि मैं गुणों को वापस डेटाफ्रेम में डाल सकूं। – tnknepp

+0

हां, लेकिन अगर आप 'setattr' का उपयोग करते हैं तो सावधानी बरतें, क्योंकि अगर आप' data.groupby (...)। Agg (...) 'जैसे कुछ कहते हैं, तो लौटाए गए डेटाफ्रेम मेटाडेटा को छोड़ सकता है। – unutbu

5

दृष्टिकोण मैं उपयोग में अतिरिक्त जानकारी मैं चाहता हूँ स्टोर करने के लिए अतिरिक्त MultiIndex स्तरों को जोड़ने के लिए है (मैं स्तंभों का उपयोग, लेकिन या तो काम करेंगे)। इन अतिरिक्त पैरामीटर के लिए सभी कॉलमों के समान मान हैं। यह भी उपयोगी है क्योंकि मैं एकाधिक डेटाफ्रेम जोड़ सकता हूं या अलग-अलग स्तंभों को विभाजित कर सकता हूं और ये मान संरक्षित हैं।

>>> col=pd.MultiIndex.from_product([['US/Eastern'], ['A', 'B', 'C', 'E', 'D']], names=['local_tz', 'name']) 
>>> a = pd.DataFrame(data=pd.np.random.randint(0,100,(10,5)),columns=col) 
>>> print(a) 
local_tz US/Eastern     
name    A B C E D 
0    38 93 63 24 55 
1    21 25 84 98 62 
2     4 60 78 0 5 
3    26 50 82 89 23 
4    32 70 80 90 1 
5     6 17 8 60 59 
6    95 98 69 19 76 
7    71 90 45 45 40 
8    94 16 44 60 16 
9    53 8 30 4 72 
+0

धन्यवाद BlackCat। यह काम करेगा, हालांकि मैं बहु-अनुक्रमण (शायद अपने स्वयं के नुकसान के लिए) से बचने की कोशिश करता हूं। – tnknepp

संबंधित मुद्दे