HOME


sh-3ll 1.0
DIR:/usr/local/lib/python3.6/site-packages/xarray/core/__pycache__/
Upload File :
Current File : //usr/local/lib/python3.6/site-packages/xarray/core/__pycache__/variable.cpython-36.pyc
3

���h���
@s<ddlmZddlZddlZddlZddlZddlZddl	m
Z
ddl	mZddl	mZddl	m
Z
ddlmZmZmZmZdd	lmZmZmZddlZyddljZWnek
r�YnXd"dd
�Zdd�Zdd�Zd#dd�Zdd�Z Gdd�de
j!e
j"�Z#ej$e#�Gdd�de#�Z%dd�Z&dd�Z'dd�Z(d d!�Z)dS)$�)�	timedeltaN�)�common)�indexing)�ops)�utils)�
basestring�OrderedDict�zip�dask_array_type)�PandasIndexAdapter�orthogonally_indexable�LazyIntegerRangeTFcCs|rt|d�r|j}t|ttjf�s�t|d�rnt|d�sBt|d�rnt|jt|d|j�t|dd�t|dd��}n�t|t	�r�yt|�}Wq�t
k
r�t
d��Yq�XnPtj|�r�tg|�}n:t|d	d�dk	r�t|j
|�}n|dk	r�t||�}nt
d
��n|�r|jdd�}|S)
a�Convert an object into an Variable

    - If the object is already an `Variable`, return it.
    - If the object is a `DataArray`, return it if `strict=False` or return
      its variable if `strict=True`.
    - Otherwise, if the object has 'dims' and 'data' attributes, convert
      it into a new `Variable`.
    - If all else fails, attempt to convert the object into an `Variable` by
      unpacking it into the arguments for `Variable.__init__`.
    �variable�dims�data�values�attrsN�encodingz(cannot convert argument into an Variable�namez cannot infer Variable dimensionsF)�deep)�hasattrr�
isinstance�Variable�xr�	DataArrayr�getattrr�tuple�	TypeErrorrZ	is_scalarr�copy)�obj�key�strictr�r#�4/tmp/pip-build-5_djhm0z/xray/xarray/core/variable.py�as_variables.





r%cCst|t|��S)zo
    This is equivalent to np.arange(size), but waits to create the array until
    its actually accessed.
    )�
Coordinater)�dim�sizer#r#r$�default_index_coordinateBsr)cCst|tj�rt|�S|S)z�
    Put pandas.Index and numpy.ndarray arguments in adapter objects to ensure
    they can be indexed properly.

    NumpyArrayAdapter, PandasIndexAdapter and LazilyIndexedArray should
    all pass through unmodified.
    )r�pd�Indexr)rr#r#r$�_maybe_wrap_dataJsr,cCs�|rt|dd�dkrt|�St|t�r*|St|tj�r>t|�St|t�rRtj|�}t|tj	�rlt
j|jd�}t|t
�r�t
jt|d|�d�}t|d�s�t|d�s�t|t
jt
jt
jt
jf�r�t
j|�}t|d|�}t|t
jj��r*t
jj|�}|j��r tj|j�\}}t
j||d�}|||<n
t
j|�}t|t
j��r�|jjd	k�rRtj|�}n6|jjd
k�rnt
j|d�}n|jjdk�r�t
j|d
�}t|�S)a�Prepare and wrap data to put in a Variable.

    - If data does not have the necessary attributes, convert it to ndarray.
    - If data has dtype=datetime64, ensure that it has ns precision. If it's a
      pandas.Timestamp, convert it to datetime64.
    - If data is already a pandas or xarray object (other than an Index), just
      use the values.

    Finally, wrap it up with an adapter if necessary.
    �ndimr�ns�value�dtype�shaper)r0�O�Mzdatetime64[ns]�mztimedelta64[ns])rr,rrr*r+rrZtuple_to_0darrayZ	Timestamp�np�
datetime64r/r�timedelta64rZstring_Zunicode_�asarray�maZMaskedArrayZgetmaskarray�anyr�_maybe_promoter0�ndarray�kindZ_possibly_convert_objects)r�fastpath�maskr0�
fill_valuer#r#r$�as_compatible_dataWs@







rAcCs`tj|�}|jdkr\|jjdkr*|j�}n2|jjdkrDtj|d�}n|jjdkr\tj|d�}|S)aReturn the given values as a numpy array, or as an individual item if
    it's a 0-dimensional object array or datetime64.

    Importantly, this function does not copy data if it is already an ndarray -
    otherwise, it will not be possible to update Variable values in place.
    rr2r3r.r4)r5r8r-r0r=�itemr6r7)rr#r#r$�_as_array_or_item�s


rCc@sbeZdZdZdudd�Zedd��Zedd	��Zed
d��Zedd
��Z	edd��Z
e
jdd��Z
dd�Zedd��Z
dd�Zdd�Zdd�Zedd��Zejdd��Zdd�Zd d!�Zd"d#�Zed$d%��Zd&d'�Zejd(d%��Zd)d*�Zd+d,�Zd-d.�Zed/d0��Zejd1d0��Zed2d3��Zejd4d3��Zdvd6d7�Zd8d9�Zdwd:d;�ZdZed<d=��Z e!j"�Z#dxd>d?�Z$d@dA�Z%dBdC�Z&dDdE�Z'dFdG�Z(dHdI�Z)dJdK�Z*dydLdM�Z+dzdNdO�Z,dPdQ�Z-dRdS�Z.dTdU�Z/dVdW�Z0dXdY�Z1dZd[�Z2d{d\d]�Z3e4d|d_d`��Z5dadb�Z6dcdd�Z7dedf�Z8dgdh�Z9edidj��Z:edkdl��Z;d}dmdn�Z<e=dodp��Z>e=d~dqdr��Z?e=dsdt��Z@dS)ra�A netcdf-like variable consisting of dimensions, data and attributes
    which describe a single Array. A single Variable object is not fully
    described outside the context of its parent Dataset (if you want such a
    fully described object, use a DataArray instead).

    The main functional difference between Variables and numpy arrays is that
    numerical operations on Variables implement array broadcasting by dimension
    name. For example, adding an Variable with dimensions `('time',)` to
    another Variable with dimensions `('space',)` results in a new Variable
    with dimensions `('time', 'space')`. Furthermore, numpy reduce operations
    like ``mean`` or ``sum`` are overwritten to take a "dimension" argument
    instead of an "axis".

    Variables are light-weight objects used as the building block for datasets.
    They are more primitive objects, so operations with them provide marginally
    higher performance than using DataArrays. However, manipulating data in the
    form of a Dataset or DataArray should almost always be preferred, because
    they can use more complete metadata in context of coordinate labels.
    NFcCsFt||d�|_|j|�|_d|_d|_|dk	r4||_|dk	rB||_dS)a�
        Parameters
        ----------
        dims : str or sequence of str
            Name(s) of the the data dimension(s). Must be either a string (only
            for 1D data) or a sequence of strings with length equal to the
            number of dimensions.
        data : array_like
            Data array which supports numpy-like data access.
        attrs : dict_like or None, optional
            Attributes to assign to the new variable. If None (default), an
            empty attribute dictionary is initialized.
        encoding : dict_like or None, optional
            Dictionary specifying how to encode this array's data into a
            serialized format like netCDF4. Currently used keys (for netCDF)
            include '_FillValue', 'scale_factor', 'add_offset' and 'dtype'.
            Well behaviored code to serialize a Variable should ignore
            unrecognized encoding items.
        )r>N)rA�_data�_parse_dimensions�_dims�_attrs�	_encodingrr)�selfrrrrr>r#r#r$�__init__�szVariable.__init__cCs|jjS)N)rDr0)rIr#r#r$r0�szVariable.dtypecCs|jjS)N)rDr1)rIr#r#r$r1�szVariable.shapecCs|j|jjS)N)r(r0�itemsize)rIr#r#r$�nbytes�szVariable.nbytescCst|jtjtf�S)N)rrDr5r<r)rIr#r#r$�
_in_memory�szVariable._in_memorycCst|jt�r|jS|jSdS)N)rrDrr)rIr#r#r$r�sz
Variable.datacCs&t|�}|j|jkrtd��||_dS)Nz0replacement data must match the Variable's shape)rAr1�
ValueErrorrD)rIrr#r#r$r�s
cCs&t|jtjtf�s tj|j�|_|jS)N)rrDr5r<rr8)rIr#r#r$�_data_cached�szVariable._data_cachedcCs
t|j�S)N)r
rD)rIr#r#r$�_indexable_dataszVariable._indexable_datacCs|j�|S)aAManually trigger loading of this variable's data from disk or a
        remote source into memory and return this variable.

        Normally, it should not be necessary to call this method in user code,
        because all xarray functions should either work on deferred data or
        load data automatically.
        )rO)rIr#r#r$�loadsz
Variable.loadcCstjdtdd�|j�S)NzGthe Variable method `load_data` has been deprecated; use `load` instead�)�
stacklevel)�warnings�warn�
FutureWarningrQ)rIr#r#r$�	load_datas
zVariable.load_datacCs|j�|jS)z7Always cache data as an in-memory array before pickling)rO�__dict__)rIr#r#r$�__getstate__szVariable.__getstate__cCst|j��S)z&The variable's data as a numpy.ndarray)rCrO)rIr#r#r$rszVariable.valuescCs
||_dS)N)r)rIrr#r#r$r"scCst|j|j|j|jdd�S)z.Return this variable as a base xarray.VariableT)rr>)rrrDrGrH)rIr#r#r$�to_variable&szVariable.to_variablecCst|j|j|j|jdd�S)z,Return this variable as an xarray.CoordinateT)rr>)r&rrDrGrH)rIr#r#r$�to_coord+szVariable.to_coordcCs|j�j�S)z'Convert this variable to a pandas.Index)r[�to_index)rIr#r#r$r\0szVariable.to_indexcCs|jS)zITuple of dimension names with which this variable is associated.
        )rF)rIr#r#r$r4sz
Variable.dimscCs<t|t�r|f}t|�}t|�|jkr8td||jf��|S)NzQdimensions %s must have the same length as the number of data dimensions, ndim=%s)rrr�lenr-rN)rIrr#r#r$rE:s
zVariable._parse_dimensionscCs|j|�|_dS)N)rErF)rIr/r#r#r$rDscs*tj��r"t�fdd�|jD��S�SdS)Nc3s|]}�j|td��VqdS)N)�get�slice)�.0r')r!r#r$�	<genexpr>Jsz.Variable._item_key_to_tuple.<locals>.<genexpr>)r�is_dict_likerr)rIr!r#)r!r$�_item_key_to_tupleHs
zVariable._item_key_to_tuplecCs�|j|�}tj||j�}tdd�t||j�D��}|j|}t|d�rh|jt	|�ks�t
|jt	|�f��nt	|�dks�t
t	|���t|�|||j|j
dd�S)a
Return a new Array object whose contents are consistent with
        getting the provided key from the underlying data.

        NB. __getitem__ and __setitem__ implement "orthogonal indexing" like
        netCDF4-python, where the key can only include integers, slices
        (including `Ellipsis`) and 1d arrays, each of which are applied
        orthogonally along their respective dimensions.

        The difference does not matter in most cases unless you are using
        numpy's "fancy indexing," which can otherwise result in data arrays
        whose shapes is inconsistent (or just uninterpretable with) with the
        variable's dimensions.

        If you really want to do indexing like `x[x > 0]`, manipulate the numpy
        array `x.values` directly.
        css&|]\}}t|ttjf�s|VqdS)N)r�intr5�integer)r`�kr'r#r#r$raasz'Variable.__getitem__.<locals>.<genexpr>r-rT)r>)rcrZexpanded_indexerr-rr
rrPrr]�AssertionError�typerGrH)rIr!rrr#r#r$�__getitem__Ns


"zVariable.__getitem__cCs6|j|�}t|jt�rtd��t|j��}|||<dS)z�__setitem__ is overloaded to access the underlying numpy values with
        orthogonal indexing.

        See __getitem__ for more details.
        z�this variable's data is stored in a dask array, which does not support item assignment. To assign to this variable, you must first load it into memory explicitly using the .load_data() method or accessing its .values attribute.N)rcrrDrrr
rO)rIr!r/rr#r#r$�__setitem__ls

zVariable.__setitem__cCs|jdkrt�|_|jS)z9Dictionary of local attributes on this variable.
        N)rGr	)rIr#r#r$r|s
zVariable.attrscCst|�|_dS)N)r	rG)rIr/r#r#r$r�scCs|jdkri|_|jS)z2Dictionary of encodings on this variable.
        N)rH)rIr#r#r$r�s
zVariable.encodingcCs0yt|�|_Wntk
r*td��YnXdS)Nz)encoding must be castable to a dictionary)�dictrHrN)rIr/r#r#r$r�sTcCs@|rt|jt�r|jj�}n|j}t|�|j||j|jdd�S)z�Returns a copy of this object.

        If `deep=True`, the data array is loaded into memory and copied onto
        the new object. Dimensions, attributes and encodings are always copied.
        T)r>)	rrrrrDrhrrGrH)rIrrr#r#r$r�s
z
Variable.copycCs|jdd�S)NF)r)r)rIr#r#r$�__copy__�szVariable.__copy__cCs|jdd�S)NT)r)r)rI�memor#r#r$�__deepcopy__�szVariable.__deepcopy__cCst|jdd�S)zYBlock dimensions for this array's data or None if it's not a dask
        array.
        �chunksN)rrD)rIr#r#r$ro�szVariable.chunkscs�ddlj}tj��r.t�fdd��j�D����dkrB�jp@�j��j}t	||j
�r`|j��}n8tj��r�t�fdd�t
�j�D���|j|�||d�}t���j|�j�jdd�S)	a�Coerce this array's data into a dask arrays with the given chunks.

        If this variable is a non-dask array, it will be converted to dask
        array. If it's a dask array, it will be rechunked to the given chunk
        sizes.

        If neither chunks is not provided for one or more dimensions, chunk
        sizes along that dimension will not be updated; non-dask arrays will be
        converted into dask arrays with a single block.

        Parameters
        ----------
        chunks : int, tuple or dict, optional
            Chunk sizes along each dimension, e.g., ``5``, ``(5, 5)`` or
            ``{'x': 5, 'y': 5}``.
        name : str, optional
            Used to generate the name for this array in the internal dask
            graph. Does not need not be unique.
        lock : optional
            Passed on to :py:func:`dask.array.from_array`, if the array is not
            already as dask array.

        Returns
        -------
        chunked : xarray.Variable
        rNc3s |]\}}�j|�|fVqdS)N)�get_axis_num)r`r'�chunk)rIr#r$ra�sz!Variable.chunk.<locals>.<genexpr>c3s|]\}}�j||�VqdS)N)r^)r`�n�s)ror#r$ra�s)r�lockT)r>)�
dask.array�arrayrrbrk�itemsror1rDr�Array�rechunkr�	enumerateZ
from_arrayrhrrGrH)rIrorrt�darr#)rorIr$rq�s


zVariable.chunkcsj�fdd�|D�}|r"td|��td�g�j}x*t�j�D]\}}||kr>||||<q>W�t|�S)alReturn a new array indexed along the specified dimension(s).

        Parameters
        ----------
        **indexers : {dim: indexer, ...}
            Keyword arguments with names matching dimensions and values given
            by integers, slice objects or arrays.

        Returns
        -------
        obj : Array object
            A new Array with the selected data and dimensions. In general,
            the new variable's data will be a view of this variable's data,
            unless numpy fancy indexing was triggered by using an array
            indexer, in which case the data will be a copy.
        csg|]}|�jkr|�qSr#)r)r`rf)rIr#r$�
<listcomp>�sz!Variable.isel.<locals>.<listcomp>zdimensions %r do not existN)rNr_r-rzrr)rIZindexers�invalidr!�ir'r#)rIr$�isel�sz
Variable.iselcCs(|j|�}|dkr td|�}n|dkr6t|d�}ntd�}|td�f||fj}tj|j�\}}t|j�}tt	|�||�||<t
|t�r�t|j�}	||f|	|<t
jtj|	d�}
ntj}
|
|||d�}|dkr�||g}n||g}tj||�}
t
|
t��r|
j|jj�}
t|�|j|
|jdd�S)Nr)ro)r0T)r>)rpr_rrr;r0�listr1�min�absrrro�	functools�partialr{�fullr5r�concatenateryrhrrG)rIr'�count�axisZkeepZtrimmed_datar0r@r1ror�Znans�arraysrr#r#r$�_shift_one_dims.




zVariable._shift_one_dimcKs*|}x |j�D]\}}|j||�}qW|S)a�
        Return a new Variable with shifted data.

        Parameters
        ----------
        **shifts : keyword arguments of the form {dim: offset}
            Integer offset to shift along each of the given dimensions.
            Positive offsets shift to the right; negative offsets shift to the
            left.

        Returns
        -------
        shifted : Variable
            Variable with the same dimensions and attributes but shifted data.
        )rwr�)rI�shifts�resultr'r�r#r#r$�shift0szVariable.shiftcs��j|��|�j�;}|dkr:t|d�td|�g}n
td�g}��fdd�|D�}tj|��}t|t�r||j�jj	�}t
���j|�jdd�S)Nrcs&g|]}�td�f�|fj�qS)N)r_r)r`�idx)r�rIr#r$r|Nsz*Variable._roll_one_dim.<locals>.<listcomp>T)r>)
rpr1r_rr�rrryrrorhrrG)rIr'r��indicesr�rr#)r�rIr$�
_roll_one_dimEs


zVariable._roll_one_dimcKs*|}x |j�D]\}}|j||�}qW|S)a�
        Return a new Variable with rolld data.

        Parameters
        ----------
        **shifts : keyword arguments of the form {dim: offset}
            Integer offset to roll along each of the given dimensions.
            Positive offsets roll to the right; negative offsets roll to the
            left.

        Returns
        -------
        shifted : Variable
            Variable with the same dimensions and attributes but rolled data.
        )rwr�)rIr�r�r'r�r#r#r$�roll[sz
Variable.rollcGsNt|�dkr|jddd�}|j|�}tj|j|�}t|�|||j|jdd�S)a�Return a new Variable object with transposed dimensions.

        Parameters
        ----------
        *dims : str, optional
            By default, reverse the dimensions. Otherwise, reorder the
            dimensions to this order.

        Returns
        -------
        transposed : Variable
            The returned object has transposed data and dimensions with the
            same attributes as the original.

        Notes
        -----
        Although this operation returns a view of this variable's data, it is
        not lazy -- the data will be fully loaded.

        See Also
        --------
        numpy.transpose
        rNrT)r>���)	r]rrpr�	transposerrhrGrH)rIrZaxesrr#r#r$r�ps

zVariable.transposecCs tt|j|j��}tj|||�S)a�Return a new Variable object with squeezed data.

        Parameters
        ----------
        dim : None or str or tuple of str, optional
            Selects a subset of the length one dimensions. If a dimension is
            selected with length greater than one, an error is raised. If
            None, all length one dimensions are squeezed.

        Returns
        -------
        squeezed : Variable
            This array, but with with all or a subset of the dimensions of
            length 1 removed.

        Notes
        -----
        Although this operation returns a view of this variable's data, it is
        not lazy -- the data will be fully loaded.

        See Also
        --------
        numpy.squeeze
        )rkr
rr1r�squeeze)rIr'rr#r#r$r��szVariable.squeezecs�t|t�r|g}|dkr*tj|�r*|j�}t|j�t|�}|rHtd��t|j��t�fdd�|D��|j}|dk	r�t	t
||����fdd�|D�}tj|j
|�}n|j
d	t|�|j}t|||j|jdd�}|j|�S)
a�Return a new variable with expanded dimensions.

        When possible, this operation does not copy this variable's data.

        Parameters
        ----------
        dims : str or sequence of str or dict
            Dimensions to include on the new variable. If a dict, values are
            used to provide the sizes of new dimensions; otherwise, new
            dimensions are inserted with length 1.

        Returns
        -------
        Variable
        Nz8new dimensions must be a superset of existing dimensionsc3s|]}|�kr|VqdS)Nr#)r`�d)�	self_dimsr#r$ra�sz'Variable.expand_dims.<locals>.<genexpr>csg|]}�|�qSr#r#)r`r�)�dims_mapr#r$r|�sz(Variable.expand_dims.<locals>.<listcomp>T)r>)N)rrrrbr�setrrNrrkr
rZbroadcast_torr]r-rrGrHr�)rIrr1Zmissing_dimsZ
expanded_dimsZ	tmp_shapeZ
expanded_dataZexpanded_varr#)r�r�r$�expand_dims�s&


zVariable.expand_dimsc	s�t��t|j�kstd���||jkr0td��t��dkrH|jdd�S�fdd�|jD�}|t��}|j|�}|jdt|��d}|jj	|�}|jdt|��|f}t
|||j|jd	d
�S)
Nzinvalid existing dimensions: %szIcannot create a new dimension with the same name as an existing dimensionrF)rcsg|]}|�kr|�qSr#r#)r`r�)rr#r$r|�sz(Variable._stack_once.<locals>.<listcomp>rT)r>r�)r�)
r�rrNr]rr�r�r1r�reshaperrGrH)	rIr�new_dim�
other_dims�	dim_order�	reordered�	new_shape�new_data�new_dimsr#)rr$�_stack_once�s

zVariable._stack_oncecKs*|}x |j�D]\}}|j||�}qW|S)as
        Stack any number of existing dimensions into a single new dimension.

        New dimensions will be added at the end, and the order of the data
        along each new dimension will be in contiguous (C) order.

        Parameters
        ----------
        **dimensions : keyword arguments of the form new_name=(dim1, dim2, ...)
            Names of new dimensions, and the existing dimensions that they
            replace.

        Returns
        -------
        stacked : Variable
            Variable with the same attributes but stacked data.

        See also
        --------
        Variable.unstack
        )rwr�)rI�
dimensionsr�r�rr#r#r$�stack�szVariable.stackcs�t|j��}t|j��}�|jkr.td���t|�j|j�rFtd��|j��}tj	|�|j
|krltd���fdd�|jD�}|�g}|j|�}|j
dt|��|}	|j
j|	�}
|jdt|��|}t||
|j|jdd�S)Nzinvalid existing dimension: %szIcannot create a new dimension with the same name as an existing dimensionzOthe product of the new dimension sizes must equal the size of the old dimensioncsg|]}|�kr|�qSr#r#)r`r�)�old_dimr#r$r|sz*Variable._unstack_once.<locals>.<listcomp>T)r>)r�keysrrrNr��intersectionrpr5�prodr1r�r]rr�rrGrH)rIrr�Z
new_dim_namesZ
new_dim_sizesr�r�r�r�r�r�r�r#)r�r$�
_unstack_onces"



zVariable._unstack_oncecKs*|}x |j�D]\}}|j||�}qW|S)au
        Unstack an existing dimension into multiple new dimensions.

        New dimensions will be added at the end, and the order of the data
        along each new dimension will be in contiguous (C) order.

        Parameters
        ----------
        **dimensions : keyword arguments of the form old_dim={dim1: size1, ...}
            Names of existing dimensions, and the new dimensions and sizes that they
            map to.

        Returns
        -------
        unstacked : Variable
            Variable with the same attributes but unstacked data.

        See also
        --------
        Variable.stack
        )rwr�)rIr�r�r�rr#r#r$�unstack szVariable.unstackcCs
|j|�S)N)Z_fillna)rIr/r#r#r$�fillna;szVariable.fillnacCs
|j|�S)N)Z_where)rIZcondr#r#r$�where>szVariable.wherec
s�|dk	r|dk	rtd��|dk	r*|j|�}||r6|jn|jfd|i|��}|dkr\t|j�ntj|�|j��fdd�t|j	�D�}|r�|j
nd}	t|||	d�S)a�Reduce this array by applying `func` along some dimension(s).

        Parameters
        ----------
        func : function
            Function which can be called in the form
            `func(x, axis=axis, **kwargs)` to return the result of reducing an
            np.ndarray over an integer valued axis.
        dim : str or sequence of str, optional
            Dimension(s) over which to apply `func`.
        axis : int or sequence of int, optional
            Axis(es) over which to apply `func`. Only one of the 'dim'
            and 'axis' arguments can be supplied. If neither are supplied, then
            the reduction is calculated over the flattened array (by calling
            `func(x)` without an axis argument).
        keep_attrs : bool, optional
            If True, the variable's attributes (`attrs`) will be copied from
            the original object to the new one.  If False (default), the new
            object will be returned without attributes.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : Array
            Array with summarized data and the indicated dimension(s)
            removed.
        Nz-cannot supply both 'axis' and 'dim' argumentsr�csg|]\}}|�kr|�qSr#r#)r`rrr')�removed_axesr#r$r|isz#Variable.reduce.<locals>.<listcomp>)r)rNrprr�ranger-r5Z
atleast_1drzrrGr)
rI�funcr'r�Z
keep_attrsZ
allow_lazy�kwargsrrrr#)r�r$�reduceAs
zVariable.reduce�
concat_dimcCs�t|t�s|j\}t|�}|d}dd�|D�}||jkrt|j|�}|j}|dkrbtj||d�}	q�tj|||d�}	nd}|f|j}tj||d�}	t	|j
�}
|s�x.|D]&}|j|jkr�td��tj
|
|j
�q�W|||	|
�S)aoConcatenate variables along a new or existing dimension.

        Parameters
        ----------
        variables : iterable of Array
            Arrays to stack together. Each variable is expected to have
            matching dimensions and shape except for along the stacked
            dimension.
        dim : str or DataArray, optional
            Name of the dimension to stack along. This can either be a new
            dimension name, in which case it is added along axis=0, or an
            existing dimension name, in which case the location of the
            dimension is unchanged. Where to insert the new dimension is
            determined by the first variable.
        positions : None or list of integer arrays, optional
            List of integer arrays which specifies the integer positions to which
            to assign each dataset along the concatenated dimension. If not
            supplied, objects are concatenated in the provided order.
        shortcut : bool, optional
            This option is used internally to speed-up groupby operations.
            If `shortcut` is True, some checks of internal consistency between
            arrays to concatenate are skipped.

        Returns
        -------
        stacked : Variable
            Concatenated Variable formed by stacking all the supplied variables
            along the given dimension.
        rcSsg|]
}|j�qSr#)r)r`�vr#r#r$r|�sz#Variable.concat.<locals>.<listcomp>N)r�zinconsistent dimensions)rrrr�rprr�Zinterleaved_concatr�r	rrNrZremove_incompatible_items)�cls�	variablesr'Z	positionsZshortcutZ	first_varr�r�rrr�varr#r#r$�concatps* 




zVariable.concatcCs|j|jkptj|j|j�S)N)rDrZarray_equivr)rI�otherr#r#r$�_data_equals�szVariable._data_equalscCs@t|d|�}y|j|jko"|j|�Sttfk
r:dSXdS)aPTrue if two Variables have the same dimensions and values;
        otherwise False.

        Variables can still be equal (like pandas objects) if they have NaN
        values in the same locations.

        This method is necessary because `v1 == v2` for Variables
        does element-wise comparisions (like numpy.ndarrays).
        rFN)rrr�r�AttributeError)rIr�r#r#r$�equals�s

zVariable.equalscCs6yt||�\}}Wnttfk
r*dSX|j|�S)z�True if two Variables have the values after being broadcast against
        each other; otherwise False.

        Variables can still be equal (like pandas objects) if they have NaN
        values in the same locations.
        F)�broadcast_variablesrNr�r�)rIr�r#r#r$�broadcast_equals�s
zVariable.broadcast_equalscCs8ytj|j|j�o|j|�Sttfk
r2dSXdS)z1Like equals, but also checks attributes.
        FN)rZ
dict_equivrr�rr�)rIr�r#r#r$�	identical�s

zVariable.identicalcCst|�|j|jj|j�S)N)rhrr�realrG)rIr#r#r$r��sz
Variable.realcCst|�|j|jj|j�S)N)rhrr�imagrG)rIr#r#r$r��sz
Variable.imagcCst|j|�S)N)rr)rIr �contextr#r#r$�__array_wrap__�szVariable.__array_wrap__cstj���fdd��}|S)Ncs|j�|jf|�|��S)N)r�r)rI�argsr�)�fr#r$r��sz Variable._unary_op.<locals>.func)r��wraps)r�r�r#)r�r$�	_unary_op�szVariable._unary_opcstj����fdd��}|S)NcsLt|tjtjf�rtSt||�\}}}�s4�||�n�||�}t||�}|S)N)rrr�Dataset�NotImplemented�_broadcast_compat_datar)rIr��	self_data�
other_datarr�r�)r��	reflexiver#r$r��s

z!Variable._binary_op.<locals>.func)r�r�)r�r�Zignored_kwargsr�r#)r�r�r$�
_binary_op�s
zVariable._binary_opcstj���fdd��}|S)NcsFt|tj�rtd��t||�\}}}||jkr6td���||�|_|S)Nz+cannot add a Dataset to a Variable in-placez0dimensions cannot change for in-place operations)rrr�rr�rrNr)rIr�r�r�r)r�r#r$r��s
z)Variable._inplace_binary_op.<locals>.func)r�r�)r�r�r#)r�r$�_inplace_binary_op�s
zVariable._inplace_binary_op)NNF)T)N)NNF)N)N)NNFF)r�NF)N)F)A�__name__�
__module__�__qualname__�__doc__rJ�propertyr0r1rLrMr�setterrOrPrQrWrYrrZr[r\rrErcrirjrrrrlrn�__hash__ro�	itertoolsr�Z_array_counterrqrr�r�r�r�r�r�r�r�r�r�r�r�r�r��classmethodr�r�r�r�r�r�r�r��staticmethodr�r�r�r#r#r#r$r�s�




0(

)
.?
	

rcsveZdZdZd�fdd�	Zdd�Zdd	�Zd
d�Zdd
d�Zdd�Z	dd�Z
dd�Zedd��Z
e
jdd��Z
�ZS)r&a�Wrapper around pandas.Index that adds xarray specific functionality.

    The most important difference is that Coordinate objects must always have a
    name, which is the dimension along which they index values.

    Coordinates must always be 1-dimensional. In addition to Variable methods
    and properties (attributes, encoding, broadcasting), they support some
    pandas.Index methods directly (e.g., get_indexer), even though pandas does
    not (yet) support duck-typing for indexes.
    NFcs8tt|�j|||||�|jdkr4tdt|�j��dS)Nrz %s objects must be 1-dimensional)�superr&rJr-rNrhr�)rIrrrrr>)�	__class__r#r$rJs
zCoordinate.__init__cCst|jt�st|j�|_|jS)N)rrDr)rIr#r#r$rOszCoordinate._data_cachedcCs\|j|�}|j|}t|d�s*|jdkr<tf||j|j�St|�|j||j|jdd�SdS)Nr-rT)r>)	rcrPrr-rrGrHrhr)rIr!rr#r#r$ri$s

zCoordinate.__getitem__cCstdt|�j��dS)Nz%s values cannot be modified)rrhr�)rIr!r/r#r#r$rj-szCoordinate.__setitem__TcCs.|rt|�n|j}t|�|j||j|jdd�S)z�Returns a copy of this object.

        If `deep=True`, the values array is loaded into memory and copied onto
        the new object. Dimensions, attributes and encodings are always copied.
        T)r>)rrDrhrrGrH)rIrrr#r#r$r0szCoordinate.copycCs|j�j|j��S)N)r\r�)rIr�r#r#r$r�<szCoordinate._data_equalscCs|S)z,Return this variable as an xarray.Coordinater#)rIr#r#r$r[?szCoordinate.to_coordcCs4|jdkst�|j�j}t|tj�s0|j|j�}|S)z'Convert this variable to a pandas.Indexr)	r-rgrOrvrr*Z
MultiIndexZ	set_namesr)rI�indexr#r#r$r\Cs

zCoordinate.to_indexcCs
|jdS)Nr)r)rIr#r#r$rMszCoordinate.namecCstd��dS)Nz)cannot modify name of Coordinate in-place)r�)rIr/r#r#r$rQs)NNF)T)r�r�r�r�rJrOrirjrr�r[r\r�rr��
__classcell__r#r#)r�r$r&s	

r&cCs�t�}x�|D]~}|j}tt|��t|�kr:tdt|���xNt||j�D]>\}}||krb|||<qH|||krHtd||||ff��qHWqW|S)Nz3broadcasting cannot handle duplicate dimensions: %rzRoperands cannot be broadcast together with mismatched lengths for dimension %r: %s)r	rr]r�rNr�r
r1)r�Zall_dimsr�Zvar_dimsr�rsr#r#r$�
_unified_dimsVs

r�cs"tt|���t�fdd�|D��S)Nc3s&|]}|j�kr|j��n|VqdS)N)rr�)r`r�)rr#r$rajsz._broadcast_compat_variables.<locals>.<genexpr>)rr�)r�r#)rr$�_broadcast_compat_variableshsr�cs(t|��t���t��fdd�|D��S)a�Given any number of variables, return variables with matching dimensions
    and broadcast data.

    The data on the returned variables will be a view of the data on the
    corresponding original arrays, but dimensions will be reordered and
    inserted so that both broadcast arrays have the same dimensions. The new
    dimensions are sorted in order of appearence in the first variable's
    dimensions followed by the second variable's dimensions.
    c3s&|]}|j�kr|j��n|VqdS)N)rr�)r`r�)r��
dims_tupler#r$razsz&broadcast_variables.<locals>.<genexpr>)r�r)r�r#)r�r�r$r�ns
r�csRt�fdd�dD��r8t|��\}}|j}|j}|j}n|j}�}|j}|||fS)Nc3s|]}t�|�VqdS)N)r)r`�attr)r�r#r$rasz)_broadcast_compat_data.<locals>.<genexpr>rrr1r)rrr1r)�allr�rr)rIr�Znew_selfZ	new_otherr�r�rr#)r�r$r�~s
r�)NTF)F)*�datetimerr�r�rTZnumpyr5Zpandasr*�rrrrZpycompatrr	r
rrr
rZxarrayrrurvr{�ImportErrorr%r)r,rArCZ
AbstractArrayZNdimSizeLenMixinrZ!inject_all_ops_and_reduce_methodsr&r�r�r�r�r#r#r#r$�<module>sD
)
>e
J