Package PyFoam :: Package Wrappers :: Module Pandas
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Wrappers.Pandas

  1  #  ICE Revision: $Id$ 
  2  """Extended version of the Pandas-Dataframe 
  3  """ 
  4   
  5  from pandas import DataFrame,Series 
  6  from numpy import hstack,unique 
  7  from math import isnan 
  8   
  9  from PyFoam.Error import error,warning,PyFoamException 
 10   
 11  from PyFoam.ThirdParty.six import string_types,text_type,u 
 12   
13 -class PyFoamDataFrame(DataFrame):
14 """This class adds some convenience functions to the regular Datafram class""" 15 16 validOtherTypes=(DataFrame,Series) 17
18 - def __init__(self,*args,**kwargs):
19 """Adds no data. Just passes the arguments to the super-class""" 20 super(PyFoamDataFrame,self).__init__(*args,**kwargs) 21 if not self.__allStrings(): 22 raise PandasWrapperPyFoamException("Columns must be strings")
23 # if not self.axes[0].is_unique: 24 # # not working as expected 25 # # self.drop_duplicates(inplace=True) 26 # self.axes[0].is_unique=True 27
28 - def __allStrings(self,keys=None):
29 if keys is None: 30 keys=self.keys() 31 return keys.map(lambda k:isinstance(k,string_types)).all()
32
33 - def addData(self,other, 34 sameIndex=True, 35 mergeIndex=False, 36 prefix=None, 37 suffix=None, 38 allowExtrapolate=False, 39 interpolationMethod="values"):
40 """Add data from another DataFrame or Series 41 @param other: data as Pandas-DataFrame or Series 42 @param sameIndex: assum both have the same indices. If False the other data will be interpolated to the current indices 43 @param mergeIndex: make the result indices a mixture of the indices""" 44 if not sameIndex and mergeIndex: 45 raise PandasWrapperPyFoamException("Can't specify sameIndex=False and mergeIndex=True at the same time") 46 if not isinstance(other,self.validOtherTypes): 47 raise PandasWrapperPyFoamException("Other data is of type",type(other), 48 "should be one of",self.validOtherTypes) 49 if isinstance(other,DataFrame): 50 o=other 51 else: 52 o=DataFrame(other) 53 54 k=o.keys() 55 if not self.__allStrings(k): 56 raise PandasWrapperPyFoamException("Added data with non-string columns") 57 v=k.copy() 58 if prefix: 59 v=[prefix+n for n in v] 60 if suffix: 61 v=[n+suffix for n in v] 62 if len(set(v)&set(self.keys()))>0: 63 raise PandasWrapperPyFoamException("Keys of this",self.keys(),"and other",v, 64 "intersect",set(v)&set(self.keys())) 65 keys=dict(zip(k,v)) 66 interpolate=False # only interpolate if necessary 67 if len(self.index)!=len(o.index) or (self.index!=o.index).any(): 68 if sameIndex and not mergeIndex: 69 raise PandasWrapperPyFoamException("Other data has different index. Specify sameIndex=False or mergeIndex=True") 70 ni=unique(hstack([self.index,o.index])) 71 interpolate=True 72 if mergeIndex: 73 minOld=min(self.index) 74 maxOld=max(self.index) 75 76 result=self.reindex(index=ni,copy=True).interpolate( 77 method=interpolationMethod,limit=1) 78 79 if not allowExtrapolate: 80 for s in result: 81 result[s][result.index<minOld]=float("NaN") 82 result[s][result.index>maxOld]=float("NaN") 83 else: 84 # make sure we have values at the current position 85 # o=o.reindex_axis(ni,axis='index').interpolate(method=interpolationMethod) 86 o=o.reindex(index=ni,columns=o.columns).interpolate(method=interpolationMethod) 87 # ,takeable=True 88 result=self.copy() 89 else: 90 result=self.copy() 91 92 minOld=min(o.index) 93 maxOld=max(o.index) 94 for k,v in keys.items(): 95 result[v]=o[k] 96 if interpolate: 97 result[v]=result[v].interpolate(method=interpolationMethod,limit=1) 98 if not allowExtrapolate: 99 result[v][result.index<minOld]=float("NaN") 100 result[v][result.index>maxOld]=float("NaN") 101 102 return PyFoamDataFrame(result)
103
104 - def integrate(self,columns=None):
105 """Integrate by using the trapezoid rule. Return a dictionary with values. 106 @param values: list of column names. If unset all are integrated""" 107 return self.__integrateInternal(columns)[0]
108
109 - def validLength(self,columns=None):
110 """Length were the values are valid (not NaN) Return a dictionary with values. 111 @param values: list of column names. If unset all are integrated""" 112 return self.__integrateInternal(columns)[1]
113
114 - def weightedAverage(self,columns=None):
115 """Weighted average. Return a dictionary with values. 116 @param values: list of column names. If unset all are integrated""" 117 integral,length=self.__integrateInternal(columns) 118 result={} 119 for k in integral: 120 if length[k]>0 and not isnan(length[k]): 121 result[k]=integral[k]/length[k] 122 else: 123 result[k]=float("NaN") 124 return result
125
126 - def __integrateInternal(self,columns):
127 if columns is None: 128 columns=self.keys() 129 integrals={} 130 lengths={} 131 ind=self.index 132 133 for k in columns: 134 integrals[k]=0 135 lengths[k]=0 136 if len(ind)<2: # no weighting possible 137 integrals[k]=float("NaN") 138 continue 139 val=self[k].values 140 for i in range(len(ind)): 141 if not isnan(val[i]): 142 w=0 143 if i>0: 144 w+=0.5*(ind[i]-ind[i-1]) 145 if i+1<len(ind): 146 w+=0.5*(ind[i+1]-ind[i]) 147 lengths[k]+=w 148 integrals[k]+=w*val[i] 149 if lengths[k]==0: 150 integrals[k]=float("NaN") 151 152 return integrals,lengths
153
154 - def describe(self,*args,**kwargs):
155 """Adds our own statistics to the regular describe""" 156 d=super(PyFoamDataFrame,self).describe(*args,**kwargs) 157 integral,length=self.__integrateInternal(self.keys()) 158 d=d.append(DataFrame(data=integral,index=["integral"])) 159 d=d.append(DataFrame(data=length,index=["valid length"])) 160 a={} 161 for k in integral: 162 if length[k]>0 and not isnan(length[k]): 163 a[k]=integral[k]/length[k] 164 else: 165 a[k]=float("NaN") 166 d=d.append(DataFrame(data=a,index=["weighted average"])) 167 return d
168
169 -class PandasWrapperPyFoamException(PyFoamException):
170 """The PyFoam-exception that does not expect to be caught""" 171
172 - def __init__(self,*text):
173 descr="Problem in wrapper to pandas-library" 174 # super(FatalErrorPyFoamException,self).__init__(descr,*text) # does not work with Python 2.4 175 PyFoamException.__init__(self,descr,*text)
176