Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Working with Xarray

From the Xarray Documentation

Multi-dimensional (a.k.a. N-dimensional, ND) arrays (sometimes called “tensors”) are an essential part of computational science. They are encountered in a wide range of fields, including physics, astronomy, geoscience, bioinformatics, engineering, finance, and deep learning. In Python, NumPy provides the fundamental data structure and API for working with raw ND arrays. However, real-world datasets are usually more than just raw numbers; they have labels which encode information about how the array values map to locations in space, time, etc.

Xarray doesn’t just keep track of labels on arrays – it uses them to provide a powerful and concise interface.

Xarray is a class of objects added to the regular python system that allows storing data in a more organized method. The format is very similar to netCDF classic model (netCDF3). It can read netCDF files efficiently and handle some issues associated with incorrectly designed netCDF files.

Xarray also has extetions to use the Numpy, Pandas, Dask and SciPy libaries directly. Think of Xarray as a tool for organizing data in a way that other libaries can be used on the data efficiently.

The primary difference between Xarray and Pandas is that Pandas is designed to handle 1-D data while Xarray can handle n-D data and metadata about the data.

Additional Tutorials:

DataArray

Here we create some data with Numpy and put into an Xarray DataArray. Notice how there is a concept of dimentionality built into DataArray. “xarray.DataArray (dim_0: 10000)”. But because we didn’t define the dimention name a generic one was created for us.

This time create a time array to match the data array shape. Time will be one minute time steps. The time array will become a coordinate variable to describe the values along the dimention we defined and named “time”. The coordinate is set to the time array and the dimention is set to “time” string.

We can add attributes describing metadata about the data.

Same as above but all in one step while creating the DataArray.

To extract the data values only we use the .values attribute on the DataArray

To extract the attributes as a dictionary we use the .attrs attribute.

Or the attrs decorator can also accept a name for a specific attribute

Dataset

The full power of Xarray comes from using Datasets. A Dataset is a collection of DataArrays. The beauty of Datasets is holding all the corresoponding data together and performing functions on multiple DataArrays in the Datasets all at once. This becomes very powerful and very fast!

Create some data and a time data array to match the data we created with minute time steps.

Print out the full Dataset

Print out one DataArray from the Dataset

Print out values from the one variable in the Dataset

Print out one attribute from one DataArray

Read in data

Let’s read in a single netCDF data file.

We can also read in multiple netCDF data files using a differnet method. All the kewords accecpted by open_dataset() are accepted by open_mfdataset().

The filename glob is understood by open_mfdataset() and correctly grabs all the files that match the file glob. Using parallel=True allows it to use multiple cores for reading the data. This may depend on your machine and number of cores available, and may be faster or may not. We can also reduce the amount of memory required by excluding some variables from being read.

To resolve issues with incorrectly formatted variables or reduce the memory we can exclude some variable from being read.

Once we have the data read, Xarray has a wrapper around matplotlib to generate plots directly from the Dataset.

Here we make two plots. Syntax is slightly different than calling matplotlib directly.

Xarray playing very well with other libraries

We can use Xarray with Pandas natively for even easier actions. Here we use pandas to make a time array with a 6 hour time step for four years.

We will create a new Xarray Dataset with a range of numbers matching the number of time samples we created. The Pandas time is used to initialize the xarray Dataset. Because Pandas and Xarray play well together it just works.

Sub-selecting data

Now let’s calculate the mean for a day by grouping the data. This works for all time worded groups: hour, minute, year, month, ... The method returns a new Dataset and leaves the orginal untouched. Notice how data was orginanally type integer, but because we are calcualting a mean, the type is upconverted to float.

We can also define the grouping size by using the .resample() method and pass in the function to use using the .reduce() method. If there is no data to perform the operation, a new time step is added with a NaN data value.

The .sel() method select data based on data or coordinate values. We can extract a range of data by filtering on the time coordinate and using the builtin slice() function. This looks familar to the Pandas example because Xarray is using Pandas.

For selecting at specific index use .isel().

What if we want to find the closes value in time but not match to values outside a tolerable range. We can use .reindex() method with a toleracne to indicate which values should be matched. The values that don’t have a match are set to NaN. We need to use timedelta64() to set the tolerance value which includes a time unit. Anywhere the time is outside the tolerance the data values is set to NaN. To allow for setting NaN, the data type is upconverted to float.

To not have a Dataset full of missing values where the time was outside the tolerance we can drop where all values are set to NaN and return a new Dataset.