U
    ½mœdz#  ã                   @   s~   d ddgZ ddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 dd „ Zd	d
„ Zdd„ Zdd„ ZG dd„ deƒZdd„ ZdS )ÚbalancedÚ	demo_dataÚLookupFactoré    N)Ú
PatsyError)ÚC)Úno_picklingÚassert_no_picklingc                     s†   |   dd¡}g }t| ƒ}|D ].‰ | ˆ  }| ‡ fdd„td|d ƒD ƒ¡ qttj|Ž Ž }i }t||ƒD ]\‰ }t|ƒ| |ˆ < qh|S )aT  balanced(factor_name=num_levels, [factor_name=num_levels, ..., repeat=1])

    Create simple balanced factorial designs for testing.

    Given some factor names and the number of desired levels for each,
    generates a balanced factorial design in the form of a data
    dictionary. For example:

    .. ipython::

       In [1]: balanced(a=2, b=3)
       Out[1]:
       {'a': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3']}

    By default it produces exactly one instance of each combination of levels,
    but if you want multiple replicates this can be accomplished via the
    `repeat` argument:

    .. ipython::

       In [2]: balanced(a=2, b=2, repeat=2)
       Out[2]:
       {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2']}
    Úrepeaté   c                    s   g | ]}d ˆ |f ‘qS )z%s%s© )Ú.0Úi©Únamer   úH/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/patsy/user_util.pyÚ
<listcomp>1   s     zbalanced.<locals>.<listcomp>)ÚpopÚsortedÚappendÚrangeÚzipÚ	itertoolsÚproductÚlist)Úkwargsr	   ÚlevelsÚnamesZlevel_countÚvaluesÚdataÚvaluer   r   r   r      s    $c                  C   s¦   t ddd�} | d ddddddgks(t‚| d dd	d
dd	d
gksDt‚t dddd�} | d ddddddddddddgkszt‚| d dd	d
dd	d
dd	d
dd	d
gks¢t‚d S )Né   é   )ÚaÚbr"   Úa1Úa2r#   Úb1Úb2Zb3)r"   r#   r	   )r   ÚAssertionError)r   r   r   r   Útest_balanced9   s(         ÿ
     ÿr)   c                  O   sî   |  dd¡}|  dd¡}|r*td|f ƒ‚tƒ }i }| D ]@}|d dkrR|||< q8|d dkrj| |¡ q8td	|f ƒ‚q8tjt| ¡ ƒt	d
�}t	t 
|d | ¡ƒ}|| }	tf d|i|—Ž}
tj d¡}t|ƒD ]}|j|	d�|
|< qÔ|
S )a?  demo_data(*names, nlevels=2, min_rows=5)

    Create simple categorical/numerical demo data.

    Pass in a set of variable names, and this function will return a simple
    data set using those variable names.

    Names whose first letter falls in the range "a" through "m" will be made
    categorical (with `nlevels` levels). Those that start with a "p" through
    "z" are numerical.

    We attempt to produce a balanced design on the categorical variables,
    repeating as necessary to generate at least `min_rows` data
    points. Categorical variables are returned as a list of strings.

    Numerical data is generated by sampling from a normal distribution. A
    fixed random seed is used, so that identical calls to demo_data() will
    produce identical results. Numerical data is returned in a numpy array.

    Example:

    .. ipython:

       In [1]: patsy.demo_data("a", "b", "x", "y")
       Out[1]:
       {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
        'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2'],
        'x': array([ 1.76405235,  0.40015721,  0.97873798,  2.2408932 ,
                     1.86755799, -0.97727788,  0.95008842, -0.15135721]),
        'y': array([-0.10321885,  0.4105985 ,  0.14404357,  1.45427351,
                     0.76103773,  0.12167502,  0.44386323,  0.33367433])}
    Únlevelsr    Úmin_rowsé   zunexpected keyword arguments %rr   ZabcdefghijklmnZpqrstuvwxyzzbad name %r)Údtypeg      ð?r	   )Úsize)r   Ú	TypeErrorÚsetÚaddr   ÚnpÚprodr   r   ÚintÚceilr   ÚrandomZRandomStater   Únormal)r   r   r*   r+   Z	numericalZcategoricalr   Zbalanced_design_sizer	   Znum_rowsr   Úrr   r   r   r   C   s(    !
c               	   C   sp  t dddƒ} t|  ¡ ƒdddgks&t‚| d ddddddddgksFt‚| d ddddddddgksft‚| d jt t¡ks~t‚| d jdks�t‚t dd	ƒ}t| ¡ ƒdd	gks²t‚t|d ƒt|d	 ƒ  krÖd
ksÜn t‚tt ddd�d ƒdksøt‚tt ddddd�d ƒdk�st‚tt dddddd�d ƒdk�s>t‚dd l	}| 
tt ddd¡ |j
tt dddd� d S )Nr"   r#   Úxr$   r%   r&   r'   )é   Úyr,   é
   )r+   é   r!   )r+   r*   é   r   Z__123é{   )Zasdfasdf)r   r   Úkeysr(   r-   r2   ÚfloatÚshapeÚlenÚpytestÚraisesr   r/   )Zd1Zd2rD   r   r   r   Útest_demo_dataz   s      
*"$rF   c                   @   sf   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZeZdS )r   a8  A simple factor class that simply looks up a named entry in the given
    data.

    Useful for programatically constructing formulas, and as a simple example
    of the factor protocol.  For details see
    :ref:`expert-model-specification`.

    Example::

      dmatrix(ModelDesc([], [Term([LookupFactor("x")])]), {"x": [1, 2, 3]})

    :arg varname: The name of this variable; used as a lookup key in the
      passed in data dictionary/DataFrame/whatever.
    :arg force_categorical: If True, then treat this factor as
      categorical. (Equivalent to using :func:`C` in a regular formula, but
      of course you can't do that with a :class:`LookupFactor`.
    :arg contrast: If given, the contrast to use; see :func:`C`. (Requires
      ``force_categorical=True``.)
    :arg levels: If given, the categorical levels; see :func:`C`. (Requires
      ``force_categorical=True``.)
    :arg origin: Either ``None``, or the :class:`Origin` of this factor for use
      in error reporting.

    .. versionadded:: 0.2.0
       The ``force_categorical`` and related arguments.
    FNc                 C   sH   || _ || _|| _|| _|| _| jsD|d k	r4tdƒ‚|d k	rDtdƒ‚d S )Nz)contrast= requires force_categorical=Truez'levels= requires force_categorical=True)Ú_varnameÚ_force_categoricalÚ	_contrastÚ_levelsÚoriginÚ
ValueError)ÚselfÚvarnameÚforce_categoricalÚcontrastr   rK   r   r   r   Ú__init__©   s    zLookupFactor.__init__c                 C   s   | j S ©N)rG   ©rM   r   r   r   r   ·   s    zLookupFactor.namec                 C   s   d| j j| jf S )Nz%s(%r))Ú	__class__Ú__name__rG   rS   r   r   r   Ú__repr__º   s    zLookupFactor.__repr__c                 C   s:   t |tƒo8| j|jko8| j|jko8| j|jko8| j|jkS rR   )Ú
isinstancer   rG   rH   rI   rJ   ©rM   Úotherr   r   r   Ú__eq__½   s    

ÿ
þ
ý
üzLookupFactor.__eq__c                 C   s
   | |k S rR   r   rX   r   r   r   Ú__ne__Ä   s    zLookupFactor.__ne__c                 C   s   t t| j| j| j| jfƒS rR   )Úhashr   rG   rH   rI   rJ   rS   r   r   r   Ú__hash__Ç   s
      ÿzLookupFactor.__hash__c                 C   s   dS )Nr   r   )rM   ÚstateZeval_envr   r   r   Úmemorize_passes_neededË   s    z#LookupFactor.memorize_passes_neededc                 C   s   dst ‚d S ©NF©r(   )rM   r^   Ú
which_passr   r   r   r   Úmemorize_chunkÎ   s    zLookupFactor.memorize_chunkc                 C   s   dst ‚d S r`   ra   )rM   r^   rb   r   r   r   Úmemorize_finishÑ   s    zLookupFactor.memorize_finishc                 C   s&   || j  }| jr"t|| j| jd�}|S )N)rP   r   )rG   rH   r   rI   rJ   )rM   Zmemorize_stater   r   r   r   r   ÚevalÔ   s    
zLookupFactor.eval)FNNN)rU   Ú
__module__Ú__qualname__Ú__doc__rQ   r   rV   rZ   r[   r]   r_   rc   rd   re   r   Ú__getstate__r   r   r   r   r   Ž   s          þ
c                  C   sh  t dƒ} |  ¡ dkst‚| t dƒks(t‚| t dƒks8t‚t| ƒtt dƒƒksPt‚t| ƒtt dƒƒksht‚|  i ddi¡dks€t‚|  i ddi¡dks˜t‚t| ƒdks¨t‚| jd ks¶t‚t ddd�}|jdksÐt‚t dd	d
dd�}| i ddddgi¡}|jdddgk�st‚|jd
k�st‚|j	dk�s,t‚dd l
}|jtt dd
d� |jtt ddd� tt dƒƒ d S )Nr"   r#   r
   r    zLookupFactor('a')Zasdf)rK   ÚcTZCONTRAST)r
   r    )rO   rP   r   r   Únc)rP   )r   )r   r   r(   r\   re   ÚreprrK   r   rP   r   rD   rE   rL   r   )Zl_aZl_with_originZl_cÚboxrD   r   r   r   Útest_LookupFactorÜ   s0     ÿrn   )Ú__all__r   Únumpyr2   Zpatsyr   Zpatsy.categoricalr   Z
patsy.utilr   r   r   r)   r   rF   Úobjectr   rn   r   r   r   r   Ú<module>	   s   
(
7N