<s> """<STR_LIT>""" <EOL> from statsmodels . compat . python import ( iterkeys , lrange , callable , string_types , <EOL> itervalues , range ) <EOL> import copy <EOL> import types <EOL> import numpy as np <EOL> __docformat__ = '<STR_LIT>' <EOL> default_namespace = { } <EOL> class Term ( object ) : <EOL> """<STR_LIT>""" <EOL> def __pow__ ( self , power ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> power = float ( power ) <EOL> except : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if power == int ( power ) : <EOL> name = '<STR_LIT>' % ( self . name , int ( power ) ) <EOL> else : <EOL> name = '<STR_LIT>' % ( self . name , power ) <EOL> value = Quantitative ( name , func = self , transform = lambda x : np . power ( x , power ) ) <EOL> value . power = power <EOL> value . namespace = self . namespace <EOL> return value <EOL> def __init__ ( self , name , func = None , termname = None ) : <EOL> self . name = name <EOL> self . __namespace = None <EOL> if termname is None : <EOL> self . termname = name <EOL> else : <EOL> self . termname = termname <EOL> if not isinstance ( self . termname , string_types ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if func : <EOL> self . func = func <EOL> def _get_namespace ( self ) : <EOL> if isinstance ( self . __namespace , np . ndarray ) : <EOL> return self . __namespace <EOL> else : return self . __namespace or default_namespace <EOL> def _set_namespace ( self , value ) : self . __namespace = value <EOL> def _del_namespace ( self ) : del self . __namespace <EOL> namespace = property ( _get_namespace , _set_namespace , _del_namespace ) <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' % self . termname <EOL> def __add__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> fother = Formula ( other , namespace = other . namespace ) <EOL> f = fother + self <EOL> if _namespace_equal ( fother . namespace , self . namespace ) : <EOL> f . namespace = self . namespace <EOL> return f <EOL> def __mul__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( other , Term ) and other . name is '<STR_LIT>' : <EOL> f = Formula ( self , namespace = self . namespace ) <EOL> elif self . name is '<STR_LIT>' : <EOL> f = Formula ( other , namespace = other . namespace ) <EOL> else : <EOL> other = Formula ( other , namespace = other . namespace ) <EOL> f = other * self <EOL> if _namespace_equal ( other . namespace , self . namespace ) : <EOL> f . namespace = self . namespace <EOL> return f <EOL> def names ( self ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( self . name , string_types ) : <EOL> return [ self . name ] <EOL> else : <EOL> return list ( self . name ) <EOL> def __call__ ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> val = self . namespace [ self . termname ] <EOL> else : <EOL> val = self . func <EOL> if callable ( val ) : <EOL> if isinstance ( val , ( Term , Formula ) ) : <EOL> val = copy . copy ( val ) <EOL> val . namespace = self . namespace <EOL> val = val ( * args , ** kw ) <EOL> val = np . asarray ( val ) <EOL> return np . squeeze ( val ) <EOL> class Factor ( Term ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , termname , keys , ordinal = False ) : <EOL> """<STR_LIT>""" <EOL> if not ordinal : <EOL> self . keys = list ( set ( keys ) ) <EOL> self . keys . sort ( ) <EOL> else : <EOL> self . keys = keys <EOL> if len ( set ( keys ) ) != len ( list ( keys ) ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> self . _name = termname <EOL> self . termname = termname <EOL> self . ordinal = ordinal <EOL> if self . ordinal : <EOL> name = self . termname <EOL> else : <EOL> name = [ '<STR_LIT>' % ( self . termname , str ( key ) ) for key in self . keys ] <EOL> Term . __init__ ( self , name , termname = self . termname , func = self . get_columns ) <EOL> def get_columns ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> v = self . namespace [ self . _name ] <EOL> while True : <EOL> if callable ( v ) : <EOL> if isinstance ( v , ( Term , Formula ) ) : <EOL> v = copy . copy ( v ) <EOL> v . namespace = self . namespace <EOL> v = v ( * args , ** kw ) <EOL> else : break <EOL> n = len ( v ) <EOL> if self . ordinal : <EOL> col = [ float ( self . keys . index ( v [ i ] ) ) for i in range ( n ) ] <EOL> return np . array ( col ) <EOL> else : <EOL> value = [ ] <EOL> for key in self . keys : <EOL> col = [ float ( ( v [ i ] == key ) ) for i in range ( n ) ] <EOL> value . append ( col ) <EOL> return np . array ( value ) <EOL> def values ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> del ( self . func ) <EOL> val = self ( * args , ** kw ) <EOL> self . func = self . get_columns <EOL> return val <EOL> def verify ( self , values ) : <EOL> """<STR_LIT>""" <EOL> s = set ( values ) <EOL> if not s . issubset ( self . keys ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> def __add__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( other , Term ) and other . name is '<STR_LIT>' : <EOL> return Formula ( self , namespace = self . namespace ) <EOL> else : <EOL> return Term . __add__ ( self , other ) <EOL> def main_effect ( self , reference = None ) : <EOL> """<STR_LIT>""" <EOL> names = self . names ( ) <EOL> if reference is None : <EOL> reference = <NUM_LIT:0> <EOL> else : <EOL> try : <EOL> reference = self . keys . index ( reference ) <EOL> except ValueError : <EOL> reference = int ( reference ) <EOL> def maineffect_func ( value , reference = reference ) : <EOL> rvalue = [ ] <EOL> keep = lrange ( value . shape [ <NUM_LIT:0> ] ) <EOL> keep . pop ( reference ) <EOL> for i in range ( len ( keep ) ) : <EOL> rvalue . append ( value [ keep [ i ] ] - value [ reference ] ) <EOL> return np . array ( rvalue ) <EOL> keep = lrange ( len ( self . names ( ) ) ) <EOL> keep . pop ( reference ) <EOL> __names = self . names ( ) <EOL> _names = [ '<STR_LIT>' % ( __names [ keep [ i ] ] , __names [ reference ] ) for i in range ( len ( keep ) ) ] <EOL> value = Quantitative ( _names , func = self , <EOL> termname = '<STR_LIT>' % self . termname , <EOL> transform = maineffect_func ) <EOL> value . namespace = self . namespace <EOL> return value <EOL> def __getitem__ ( self , key ) : <EOL> """<STR_LIT>""" <EOL> if not self . ordinal : <EOL> i = self . names ( ) . index ( '<STR_LIT>' % ( self . termname , str ( key ) ) ) <EOL> return self ( ) [ i ] <EOL> else : <EOL> v = self . namespace [ self . _name ] <EOL> return np . array ( [ ( vv == key ) for vv in v ] ) . astype ( np . float ) <EOL> class Quantitative ( Term ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name , func = None , termname = None , transform = lambda x : x ) : <EOL> self . transform = transform <EOL> Term . __init__ ( self , name , func = func , termname = termname ) <EOL> def __call__ ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> return self . transform ( Term . __call__ ( self , * args , ** kw ) ) <EOL> class Formula ( object ) : <EOL> """<STR_LIT>""" <EOL> def _get_namespace ( self ) : <EOL> if isinstance ( self . __namespace , np . ndarray ) : <EOL> return self . __namespace <EOL> else : return self . __namespace or default_namespace <EOL> def _set_namespace ( self , value ) : self . __namespace = value <EOL> def _del_namespace ( self ) : del self . __namespace <EOL> namespace = property ( _get_namespace , _set_namespace , _del_namespace ) <EOL> def _terms_changed ( self ) : <EOL> self . _names = self . names ( ) <EOL> self . _termnames = self . termnames ( ) <EOL> def __init__ ( self , termlist , namespace = default_namespace ) : <EOL> """<STR_LIT>""" <EOL> self . __namespace = namespace <EOL> if isinstance ( termlist , Formula ) : <EOL> self . terms = copy . copy ( list ( termlist . terms ) ) <EOL> elif isinstance ( termlist , list ) : <EOL> self . terms = termlist <EOL> elif isinstance ( termlist , Term ) : <EOL> self . terms = [ termlist ] <EOL> else : <EOL> raise ValueError <EOL> self . _terms_changed ( ) <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> value = [ ] <EOL> for term in self . terms : <EOL> value += [ term . termname ] <EOL> return '<STR_LIT>' % '<STR_LIT>' . join ( value ) <EOL> def __call__ ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' in kw : <EOL> namespace = kw [ '<STR_LIT>' ] <EOL> else : <EOL> namespace = self . namespace <EOL> allvals = [ ] <EOL> intercept = False <EOL> iindex = <NUM_LIT:0> <EOL> for t in self . terms : <EOL> t = copy . copy ( t ) <EOL> t . namespace = namespace <EOL> val = t ( * args , ** kw ) <EOL> isintercept = False <EOL> if hasattr ( t , "<STR_LIT>" ) : <EOL> if t . termname == '<STR_LIT>' : <EOL> intercept = True <EOL> isintercept = True <EOL> interceptindex = iindex <EOL> allvals . append ( None ) <EOL> if val . ndim == <NUM_LIT:1> and not isintercept : <EOL> val . shape = ( <NUM_LIT:1> , val . shape [ <NUM_LIT:0> ] ) <EOL> allvals . append ( val ) <EOL> elif not isintercept : <EOL> allvals . append ( val ) <EOL> iindex += <NUM_LIT:1> <EOL> if not intercept : <EOL> try : <EOL> allvals = np . concatenate ( allvals ) <EOL> except : <EOL> pass <EOL> else : <EOL> nrow = kw . get ( '<STR_LIT>' , - <NUM_LIT:1> ) <EOL> if allvals != [ ] : <EOL> if interceptindex > <NUM_LIT:0> : <EOL> n = allvals [ <NUM_LIT:0> ] . shape [ <NUM_LIT:1> ] <EOL> else : <EOL> n = allvals [ <NUM_LIT:1> ] . shape [ <NUM_LIT:1> ] <EOL> allvals [ interceptindex ] = np . ones ( ( <NUM_LIT:1> , n ) , np . float64 ) <EOL> allvals = np . concatenate ( allvals ) <EOL> elif nrow <= <NUM_LIT:1> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> else : <EOL> allvals = I ( nrow = nrow ) <EOL> allvals . shape = ( <NUM_LIT:1> , ) + allvals . shape <EOL> return np . squeeze ( allvals ) <EOL> def hasterm ( self , query_term ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( query_term , Formula ) : <EOL> if isinstance ( query_term , string_types ) : <EOL> try : <EOL> query = self [ query_term ] <EOL> return query . termname in self . termnames ( ) <EOL> except : <EOL> return False <EOL> elif isinstance ( query_term , Term ) : <EOL> return query_term . termname in self . termnames ( ) <EOL> elif len ( query_term . terms ) == <NUM_LIT:1> : <EOL> query_term = query_term . terms [ <NUM_LIT:0> ] <EOL> return query_term . termname in self . termnames ( ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> def __getitem__ ( self , name ) : <EOL> t = self . termnames ( ) <EOL> if name in t : <EOL> return self . terms [ t . index ( name ) ] <EOL> else : <EOL> raise KeyError ( '<STR_LIT>' % repr ( name ) ) <EOL> def termcolumns ( self , query_term , dict = False ) : <EOL> """<STR_LIT>""" <EOL> if self . hasterm ( query_term ) : <EOL> names = query_term . names ( ) <EOL> value = { } <EOL> for name in names : <EOL> value [ name ] = self . _names . index ( name ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if dict : <EOL> return value <EOL> else : <EOL> return list ( itervalues ( value ) ) <EOL> def names ( self ) : <EOL> """<STR_LIT>""" <EOL> allnames = [ ] <EOL> for term in self . terms : <EOL> allnames += term . names ( ) <EOL> return allnames <EOL> def termnames ( self ) : <EOL> """<STR_LIT>""" <EOL> names = [ ] <EOL> for term in self . terms : <EOL> names += [ term . termname ] <EOL> return names <EOL> def design ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> return self ( * args , ** kw ) . T <EOL> def __mul__ ( self , other , nested = False ) : <EOL> """<STR_LIT>""" <EOL> other = Formula ( other ) <EOL> selftermnames = self . termnames ( ) <EOL> othertermnames = other . termnames ( ) <EOL> I = len ( selftermnames ) <EOL> J = len ( othertermnames ) <EOL> terms = [ ] <EOL> termnames = [ ] <EOL> for i in range ( I ) : <EOL> for j in range ( J ) : <EOL> termname = '<STR_LIT>' % ( str ( selftermnames [ i ] ) , str ( othertermnames [ j ] ) ) <EOL> pieces = sorted ( termname . split ( '<STR_LIT:*>' ) ) <EOL> termname = '<STR_LIT:*>' . join ( pieces ) <EOL> termnames . append ( termname ) <EOL> selfnames = self . terms [ i ] . names ( ) <EOL> othernames = other . terms [ j ] . names ( ) <EOL> if self . terms [ i ] . name is '<STR_LIT>' : <EOL> _term = other . terms [ j ] <EOL> _term . namespace = other . namespace <EOL> elif other . terms [ j ] . name is '<STR_LIT>' : <EOL> _term = self . terms [ i ] <EOL> _term . namespace = self . namespace <EOL> else : <EOL> names = [ ] <EOL> d1 = len ( selfnames ) <EOL> d2 = len ( othernames ) <EOL> for r in range ( d1 ) : <EOL> for s in range ( d2 ) : <EOL> name = '<STR_LIT>' % ( str ( selfnames [ r ] ) , str ( othernames [ s ] ) ) <EOL> pieces = sorted ( name . split ( '<STR_LIT:*>' ) ) <EOL> name = '<STR_LIT:*>' . join ( pieces ) <EOL> names . append ( name ) <EOL> def product_func ( value , d1 = d1 , d2 = d2 ) : <EOL> out = [ ] <EOL> for r in range ( d1 ) : <EOL> for s in range ( d2 ) : <EOL> out . append ( value [ r ] * value [ d1 + s ] ) <EOL> return np . array ( out ) <EOL> cself = copy . copy ( self . terms [ i ] ) <EOL> cother = copy . copy ( other . terms [ j ] ) <EOL> sumterms = cself + cother <EOL> sumterms . terms = [ cself , cother ] <EOL> _term = Quantitative ( names , func = sumterms , <EOL> termname = termname , <EOL> transform = product_func ) <EOL> if _namespace_equal ( self . namespace , other . namespace ) : <EOL> _term . namespace = self . namespace <EOL> terms . append ( _term ) <EOL> return Formula ( terms ) <EOL> def __add__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> other = Formula ( other ) <EOL> terms = self . terms + other . terms <EOL> pieces = sorted ( [ ( term . name , term ) for term in terms ] ) <EOL> terms = [ piece [ <NUM_LIT:1> ] for piece in pieces ] <EOL> f = Formula ( terms ) <EOL> if _namespace_equal ( self . namespace , other . namespace ) : <EOL> f . namespace = self . namespace <EOL> return f <EOL> def __sub__ ( self , other ) : <EOL> """<STR_LIT>""" <EOL> other = Formula ( other ) <EOL> terms = copy . copy ( self . terms ) <EOL> for term in other . terms : <EOL> for i in range ( len ( terms ) ) : <EOL> if terms [ i ] . termname == term . termname : <EOL> terms . pop ( i ) <EOL> break <EOL> f = Formula ( terms ) <EOL> f . namespace = self . namespace <EOL> return f <EOL> def isnested ( A , B , namespace = None ) : <EOL> """<STR_LIT>""" <EOL> if namespace is not None : <EOL> A = copy . copy ( A ) ; A . namespace = namespace <EOL> B = copy . copy ( B ) ; B . namespace = namespace <EOL> a = A ( values = True ) [ <NUM_LIT:0> ] <EOL> b = B ( values = True ) [ <NUM_LIT:0> ] <EOL> if len ( a ) != len ( b ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> nA = len ( set ( a ) ) <EOL> nB = len ( set ( b ) ) <EOL> n = max ( nA , nB ) <EOL> AB = [ ( a [ i ] , b [ i ] ) for i in range ( len ( a ) ) ] <EOL> nAB = len ( set ( AB ) ) <EOL> if nAB == n : <EOL> if nA > nB : <EOL> F = A <EOL> else : <EOL> F = B <EOL> return ( True , F ) <EOL> else : <EOL> return ( False , None ) <EOL> def _intercept_fn ( nrow = <NUM_LIT:1> , ** extra ) : <EOL> return np . ones ( ( <NUM_LIT:1> , nrow ) ) <EOL> I = Term ( '<STR_LIT>' , func = _intercept_fn ) <EOL> I . __doc__ = """<STR_LIT>""" <EOL> def interactions ( terms , order = [ <NUM_LIT:1> , <NUM_LIT:2> ] ) : <EOL> """<STR_LIT>""" <EOL> l = len ( terms ) <EOL> values = { } <EOL> if np . asarray ( order ) . shape == ( ) : <EOL> order = lrange ( <NUM_LIT:1> , int ( order ) + <NUM_LIT:1> ) <EOL> for o in order : <EOL> I = np . indices ( ( l , ) * ( o ) ) <EOL> I . shape = ( I . shape [ <NUM_LIT:0> ] , np . product ( I . shape [ <NUM_LIT:1> : ] ) ) <EOL> for m in range ( I . shape [ <NUM_LIT:1> ] ) : <EOL> if ( np . unique ( I [ : , m ] ) . shape == I [ : , m ] . shape and <EOL> np . alltrue ( np . equal ( np . sort ( I [ : , m ] ) , I [ : , m ] ) ) ) : <EOL> ll = [ terms [ j ] for j in I [ : , m ] ] <EOL> v = ll [ <NUM_LIT:0> ] <EOL> for ii in range ( len ( ll ) - <NUM_LIT:1> ) : <EOL> v *= ll [ ii + <NUM_LIT:1> ] <EOL> values [ tuple ( I [ : , m ] ) ] = v <EOL> key = list ( iterkeys ( values ) ) [ <NUM_LIT:0> ] <EOL> value = values [ key ] ; del ( values [ key ] ) <EOL> for v in itervalues ( values ) : <EOL> value += v <EOL> return value <EOL> def _namespace_equal ( space1 , space2 ) : <EOL> return space1 is space2 </s>
