<commit_before>.. _data structures:

Data Structures
===============

.. ipython:: python
   :suppress:

    import numpy as np
    import pandas as pd
    import xray
    np.random.seed(123456)
    np.set_printoptions(threshold=10)

DataArray
---------

:py:class:`xray.DataArray` is xray's implementation of a labeled,
multi-dimensional array. It has several key properties:

- ``values``: a :py:class:`numpy.ndarray` holding the array's values
- ``dims``: dimension names for each axis (e.g., ``('x', 'y', 'z')``)
- ``coords``: a dict-like container of arrays (*coordinates*) that label each
  point (e.g., 1-dimensional arrays of numbers, datetime objects or
  strings)
- ``attrs``: an ``OrderedDict`` to hold arbitrary metadata (*attributes*)

xray uses ``dims`` and ``coords`` to enable its core metadata aware operations.
Dimensions provide names that xray uses instead of the ``axis`` argument found
in many numpy functions. Coordinates enable fast label based indexing and
alignment, building on the functionality of the ``index`` found on a pandas
:py:class:`~pandas.DataFrame` or :py:class:`~pandas.Series`.

DataArray objects also can have a ``name`` and can hold arbitrary metadata in
the form of their ``attrs`` property (an ordered dictionary). Names and
attributes are strictly for users and user-written code: xray makes no attempt
to interpret them, and propagates them only in unambiguous cases (see FAQ,
:ref:`approach to metadata`).

.. _creating a dataarray:

Creating a DataArray
~~~~~~~~~~~~~~~~~~~~

The :py:class:`~xray.DataArray` constructor takes:

 - ``data``: a multi-dimensional array of values (e.g., a numpy ndarray,
:py:class:`~pandas.Series`, :py:class:`~pandas.DataFrame` or :py:class:`~pandas.Panel`)
 - ``coords``: a list or dictionary of coordinates
 - ``dims``: a list of dimension names. If omitted, dimension names are
 taken from ``coords`` if possible
 - ``attrs``: a dictionary of attributes to add to the instance
 - ``name``: a string that names the instance

.. ipython:: python

    data = np.random.rand(4, 3)
    locs = ['IA', 'IL', 'IN']
    times = pd.date_range('2000-01-01', periods=4)
    foo = xray.DataArray(data, coords=[times, locs], dims=['time', 'space'])
    foo

Only ``data`` is required; all of other arguments will be filled
in with default values:

.. ipython:: python

    xray.DataArray(data)

As you can see, dimensions and coordinate arrays corresponding to each
dimension are always present. This behavior is similar to pandas, which fills
in index values in the same way.

Coordinates can take the following forms:

- A list of ``(dim, ticks[, attrs])`` pairs with length equal to the number of dimensions
- A dictionary of ``{coord_name: coord}`` where the values are scaler values,
 1D arrays or tuples (tuples in the same form as above). This form lets you supply other
 coordinates than those corresponding to dimensions (more on these later).

As a list of tuples:

.. ipython:: python

    xray.DataArray(data, coords=[('time', times), ('space', locs)])

As a dictionary:

.. ipython:: python

    xray.DataArray(data, coords={'time': times, 'space': locs, 'const': 42,
                                 'ranking': ('space', [1, 2, 3])},
                   dims=['time', 'space'])

If you create a ``DataArray`` by supplying a pandas
:py:class:`~pandas.Series`, :py:class:`~pandas.DataFrame` or
:py:class:`~pandas.Panel`, any non-specified arguments in the
``DataArray`` constructor will be filled in from the pandas object:

.. ipython:: python

    df = pd.DataFrame({'x': [0, 1], 'y': [2, 3]}, index=['a', 'b'])
    df.index.name = 'abc'<commit_msg>spaces are important in the docs<commit_after>.. _data structures:

Data Structures
===============

.. ipython:: python
   :suppress:

    import numpy as np
    import pandas as pd
    import xray
    np.random.seed(123456)
    np.set_printoptions(threshold=10)

DataArray
---------

:py:class:`xray.DataArray` is xray's implementation of a labeled,
multi-dimensional array. It has several key properties:

- ``values``: a :py:class:`numpy.ndarray` holding the array's values
- ``dims``: dimension names for each axis (e.g., ``('x', 'y', 'z')``)
- ``coords``: a dict-like container of arrays (*coordinates*) that label each
  point (e.g., 1-dimensional arrays of numbers, datetime objects or
  strings)
- ``attrs``: an ``OrderedDict`` to hold arbitrary metadata (*attributes*)

xray uses ``dims`` and ``coords`` to enable its core metadata aware operations.
Dimensions provide names that xray uses instead of the ``axis`` argument found
in many numpy functions. Coordinates enable fast label based indexing and
alignment, building on the functionality of the ``index`` found on a pandas
:py:class:`~pandas.DataFrame` or :py:class:`~pandas.Series`.

DataArray objects also can have a ``name`` and can hold arbitrary metadata in
the form of their ``attrs`` property (an ordered dictionary). Names and
attributes are strictly for users and user-written code: xray makes no attempt
to interpret them, and propagates them only in unambiguous cases (see FAQ,
:ref:`approach to metadata`).

.. _creating a dataarray:

Creating a DataArray
~~~~~~~~~~~~~~~~~~~~

The :py:class:`~xray.DataArray` constructor takes:

- ``data``: a multi-dimensional array of values (e.g., a numpy ndarray,
  :py:class:`~pandas.Series`, :py:class:`~pandas.DataFrame` or :py:class:`~pandas.Panel`)
- ``coords``: a list or dictionary of coordinates
- ``dims``: a list of dimension names. If omitted, dimension names are
  taken from ``coords`` if possible
- ``attrs``: a dictionary of attributes to add to the instance
- ``name``: a string that names the instance

.. ipython:: python

    data = np.random.rand(4, 3)
    locs = ['IA', 'IL', 'IN']
    times = pd.date_range('2000-01-01', periods=4)
    foo = xray.DataArray(data, coords=[times, locs], dims=['time', 'space'])
    foo

Only ``data`` is required; all of other arguments will be filled
in with default values:

.. ipython:: python

    xray.DataArray(data)

As you can see, dimensions and coordinate arrays corresponding to each
dimension are always present. This behavior is similar to pandas, which fills
in index values in the same way.

Coordinates can take the following forms:

- A list of ``(dim, ticks[, attrs])`` pairs with length equal to the number of dimensions
- A dictionary of ``{coord_name: coord}`` where the values are scaler values,
  1D arrays or tuples (tuples in the same form as above). This form lets you supply other
  coordinates than those corresponding to dimensions (more on these later).

As a list of tuples:

.. ipython:: python

    xray.DataArray(data, coords=[('time', times), ('space', locs)])

As a dictionary:

.. ipython:: python

    xray.DataArray(data, coords={'time': times, 'space': locs, 'const': 42,
                                 'ranking': ('space', [1, 2, 3])},
                   dims=['time', 'space'])

If you create a ``DataArray`` by supplying a pandas
:py:class:`~pandas.Series`, :py:class:`~pandas.DataFrame` or
:py:class:`~pandas.Panel`, any non-specified arguments in the
``DataArray`` constructor will be filled in from the pandas object:

.. ipython:: python

    df = pd.DataFrame({'x': [0, 1], 'y': [2, 3]}, index=['a', 'b'])
    df.index.name = 'abc'
{'fraction_non_alphanumeric': 0.1395412718033237, 'fraction_numerical': 0.008240626287597858, 'mean_word_length': 4.106591865357644, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3478888', 'n_tokens_mistral': 2245, 'n_tokens_neox': 2155, 'n_words': 890}