---
title: DataArray
aliases:
  - ../dataarray.html
---

The [DataArray](`mikeio.DataArray`) is the common MIKE IO data structure 
for *item* data from dfs files. 
The [](`mikeio.read`) methods returns a Dataset as a container of DataArrays (Dfs items)

Each DataArray have the following properties:

* **item** - an  [](`mikeio.ItemInfo`) with name, type and unit
* **time** - a [](`pandas.DatetimeIndex`) with the time instances of the data
* **geometry** - a Geometry object with the spatial description of the data
* **values** - a [](`numpy.ndarray`)

Use DataArray's string representation to get an overview of the DataArray


```{python}
import mikeio

ds = mikeio.read("../data/HD2D.dfsu")
da = ds["Surface elevation"]
da
```


## {{< fa calendar >}} Temporal selection

```{python}
da.sel(time="1985-08-06 12:00")
```

```{python}
da["1985-8-7":]
```

## {{< fa map >}} Spatial selection
             
The [`sel`](`mikeio.DataArray.sel`) method finds the nearest element.

```{python}
da.sel(x=607002, y=6906734)
```

## Modifying values

You can modify the values of a DataArray by changing its [`values`](`mikeio.DataArray.values`): 

```{python}
da.values[0, 3] = 5.0
```

If you wish to change values of a subset of the DataArray you should be aware of the difference between a _view_ and a _copy_ of the data. Similar to NumPy, MIKE IO selection method will return a _view_ of the data when using single index and slices, but a _copy_ of the data using fancy indexing (a list of indicies or boolean indexing). Note that prior to release 1.3, MIKE IO would always return a copy. 

It is recommended to change the values using `values` property directly on the original DataArray (like above), but it is also possible to change the values of the original DataArray by working on a subset DataArray if it is selected with single index or slice as explained above. 

```{python}
da_sub = da.isel(time=0)
da_sub.values[:] = 5.0    # will change da
```

Fancy indexing will return a _copy_ and therefore not change the original:

```{python}
da_sub = da.isel(time=[0,1,2])
da_sub.values[:] = 5.0    # will NOT change da
```




## {{< fa chart-line >}} Plotting

The plotting of a DataArray is context-aware meaning that plotting behaviour depends on the geometry of the DataArray being plotted. 

```{python}
da.plot()
```

```{python}
da.plot.contourf()
```

```{python}
da.plot.mesh()
```

See details in the [API specification](`mikeio.dataset._data_plot._DataArrayPlotter`) below and in the bottom of the relevant pages e.g. [DataArray Plotter Grid2D API](`mikeio.dataset._data_plot._DataArrayPlotterGrid2D`).



## Properties

The DataArray has several properties:

* time - Time index
* geometry - geometry of the data (e.g. `spatial.GeometryFM2D`)
* shape - Shape of the data
* deletevalue - File delete value (NaN value)

```{python}
da.geometry
```


## Methods

DataArray has several useful methods for working with data, 
including different ways of *selecting* data:

* [`sel()`](`mikeio.DataArray.sel`) - Select subset along an axis
* [`isel()`](`mikeio.DataArray.isel`) - Select subset along an axis with an integer

###  Aggregations along an axis

* [`mean()`](`mikeio.DataArray.mean`) - Mean value along an axis
* [`nanmean()`](`mikeio.DataArray.nanmean`) - Mean value along an axis (NaN removed)
* [`max()`](`mikeio.DataArray.max`) - Max value along an axis
* [`nanmax()`](`mikeio.DataArray.nanmax`) - Max value along an axis (NaN removed)
* [`min()`](`mikeio.DataArray.min`) - Min value along an axis
* [`nanmin()`](`mikeio.DataArray.nanmin`) - Min value along an axis (NaN removed)
* [`aggregate()`](`mikeio.DataArray.aggregate`) - Aggregate along an axis
* [`quantile()`](`mikeio.DataArray.quantile`) - Quantiles along an axis

## {{< fa calculator >}} Mathematical operations
* ds + value
* ds - value
* ds * value

and + and - between two DataArrays (if number of items and shapes conform):

* ds1 + ds2
* ds1 - ds2

## Multiply or add scalar

```{python}
da1 = mikeio.read("../data/oresundHD_run1.dfsu", items="Surface elevation")[0]
da2 = mikeio.read("../data/oresundHD_run2.dfsu", items="Surface elevation")[0]

da1.values.mean()
```

```{python}
da1_A = da1 + 1
da1_B = da1 - 1
da1_A.values.mean(), da1_B.values.mean()
```

```{python}
da1_C = da1 * 2
da1_D = da1 / 2
da1_C.values.mean(), da1_D.values.mean()
```

## Difference between two DataArrays

Assume that we have two calibration runs and we wan't to find the difference...

```{python}
da_diff = da1-da2
da_diff.plot(title="Difference");
```

```{python}
da_ratio = da1 / da2
da_ratio.plot(title="", label="Ratio", vmin=0.8, vmax=1.2, levels=9, cmap="coolwarm")
```

Other methods that also return a DataArray:

* [`interp_like`](`mikeio.DataArray.interp_like`) - Spatio (temporal) interpolation (see example [Dfsu interpolation](../examples/Dfsu-2D-interpolation.qmd))
* [`interp_time()`](`mikeio.DataArray.interp_time`) - Temporal interpolation (see example [Time interpolation](../examples/Time-interpolation.qmd))
* [`dropna()`](`mikeio.DataArray.dropna`) - Remove time steps where all items are NaN
* [`squeeze()`](`mikeio.DataArray.squeeze`) - Remove axes of length 1

### Conversion:

* [`to_xarray()`](`mikeio.DataArray.to_xarray`) - Convert DataArray to a xarray DataArray (great for Dfs2)
* [`to_dfs()`](`mikeio.DataArray.to_dfs`) - Write DataArray to a Dfs file



