Reshaping and reorganizing data refers to the process of changing the structure or organization of data by modifying dimensions, array shapes, order of values, or indexes. Xarray provides several methods to accomplish these tasks.
These methods are particularly useful for reshaping xarray objects for use in machine learning packages, such as scikit-learn, that usually require two-dimensional numpy arrays as inputs. Reshaping can also be required before passing data to external visualization tools, for example geospatial data might expect input organized into a particular format corresponding to stacks of satellite images.
Importing the library# Reordering dimensions#To reorder dimensions on a DataArray
or across all variables on a Dataset
, use transpose()
. An ellipsis (…) can be used to represent all other dimensions:
ds = xr.Dataset({"foo": (("x", "y", "z"), [[[42]]]), "bar": (("y", "z"), [[24]])}) ds.transpose("y", "z", "x") # equivalent to ds.transpose(..., "x")
<xarray.Dataset> Size: 16B Dimensions: (x: 1, y: 1, z: 1) Dimensions without coordinates: x, y, z Data variables: foo (y, z, x) int64 8B 42 bar (y, z) int64 8B 24
foo
(y, z, x)
int64
42
bar
(y, z)
int64
24
ds.transpose() # reverses all dimensions
<xarray.Dataset> Size: 16B Dimensions: (x: 1, y: 1, z: 1) Dimensions without coordinates: x, y, z Data variables: foo (z, y, x) int64 8B 42 bar (z, y) int64 8B 24
foo
(z, y, x)
int64
42
bar
(z, y)
int64
24
To expand a DataArray
or all variables on a Dataset
along a new dimension, use expand_dims()
expanded = ds.expand_dims("w") expanded
<xarray.Dataset> Size: 16B Dimensions: (w: 1, x: 1, y: 1, z: 1) Dimensions without coordinates: w, x, y, z Data variables: foo (w, x, y, z) int64 8B 42 bar (w, y, z) int64 8B 24
foo
(w, x, y, z)
int64
42
bar
(w, y, z)
int64
24
This method attaches a new dimension with size 1 to all data variables.
To remove such a size-1 dimension from the DataArray
or Dataset
, use squeeze()
<xarray.Dataset> Size: 16B Dimensions: (x: 1, y: 1, z: 1) Dimensions without coordinates: x, y, z Data variables: foo (x, y, z) int64 8B 42 bar (y, z) int64 8B 24
foo
(x, y, z)
int64
42
bar
(y, z)
int64
24
To convert from a Dataset to a DataArray, use to_dataarray()
:
arr = ds.to_dataarray() arr
<xarray.DataArray (variable: 2, x: 1, y: 1, z: 1)> Size: 16B array([[[[42]]], [[[24]]]]) Coordinates: * variable (variable) object 16B 'foo' 'bar' Dimensions without coordinates: x, y, z
42 24
array([[[[42]]], [[[24]]]])
variable
(variable)
object
'foo' 'bar'
array(['foo', 'bar'], dtype=object)
PandasIndex
PandasIndex(Index(['foo', 'bar'], dtype='object', name='variable'))
This method broadcasts all data variables in the dataset against each other, then concatenates them along a new dimension into a new array while preserving coordinates.
To convert back from a DataArray to a Dataset, use to_dataset()
:
arr.to_dataset(dim="variable")
<xarray.Dataset> Size: 16B Dimensions: (x: 1, y: 1, z: 1) Dimensions without coordinates: x, y, z Data variables: foo (x, y, z) int64 8B 42 bar (x, y, z) int64 8B 24
foo
(x, y, z)
int64
42
bar
(x, y, z)
int64
24
The broadcasting behavior of to_dataarray
means that the resulting array includes the union of data variable dimensions:
ds2 = xr.Dataset({"a": 0, "b": ("x", [3, 4, 5])}) # the input dataset has 4 elements ds2
<xarray.Dataset> Size: 32B Dimensions: (x: 3) Dimensions without coordinates: x Data variables: a int64 8B 0 b (x) int64 24B 3 4 5
a
()
int64
0
b
(x)
int64
3 4 5
# the resulting array has 6 elements ds2.to_dataarray()
<xarray.DataArray (variable: 2, x: 3)> Size: 48B array([[0, 0, 0], [3, 4, 5]]) Coordinates: * variable (variable) object 16B 'a' 'b' Dimensions without coordinates: x
0 0 0 3 4 5
array([[0, 0, 0], [3, 4, 5]])
variable
(variable)
object
'a' 'b'
array(['a', 'b'], dtype=object)
PandasIndex
PandasIndex(Index(['a', 'b'], dtype='object', name='variable'))
Otherwise, the result could not be represented as an orthogonal array.
If you use to_dataset
without supplying the dim
argument, the DataArray will be converted into a Dataset of one variable:
arr.to_dataset(name="combined")
<xarray.Dataset> Size: 32B Dimensions: (variable: 2, x: 1, y: 1, z: 1) Coordinates: * variable (variable) object 16B 'foo' 'bar' Dimensions without coordinates: x, y, z Data variables: combined (variable, x, y, z) int64 16B 42 24
variable
(variable)
object
'foo' 'bar'
array(['foo', 'bar'], dtype=object)
combined
(variable, x, y, z)
int64
42 24
array([[[[42]]], [[[24]]]])
PandasIndex
PandasIndex(Index(['foo', 'bar'], dtype='object', name='variable'))
As part of xarray’s nascent support for pandas.MultiIndex
, we have implemented stack()
and unstack()
method, for combining or splitting dimensions:
array = xr.DataArray( np.random.randn(2, 3), coords=[("x", ["a", "b"]), ("y", [0, 1, 2])] ) stacked = array.stack(z=("x", "y")) stacked
<xarray.DataArray (z: 6)> Size: 48B array([ 0.4691123 , -0.28286334, -1.5090585 , -1.13563237, 1.21211203, -0.17321465]) Coordinates: * z (z) object 48B MultiIndex * x (z) <U1 24B 'a' 'a' 'a' 'b' 'b' 'b' * y (z) int64 48B 0 1 2 0 1 2
0.4691 -0.2829 -1.509 -1.136 1.212 -0.1732
array([ 0.4691123 , -0.28286334, -1.5090585 , -1.13563237, 1.21211203, -0.17321465])
z
(z)
object
MultiIndex
[6 values with dtype=object]
x
(z)
<U1
'a' 'a' 'a' 'b' 'b' 'b'
[6 values with dtype=<U1]
y
(z)
int64
0 1 2 0 1 2
[6 values with dtype=int64]
PandasMultiIndex
PandasIndex(MultiIndex([('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2)], name='z'))
<xarray.DataArray (x: 2, y: 3)> Size: 48B array([[ 0.4691123 , -0.28286334, -1.5090585 ], [-1.13563237, 1.21211203, -0.17321465]]) Coordinates: * x (x) <U1 8B 'a' 'b' * y (y) int64 24B 0 1 2
0.4691 -0.2829 -1.509 -1.136 1.212 -0.1732
array([[ 0.4691123 , -0.28286334, -1.5090585 ], [-1.13563237, 1.21211203, -0.17321465]])
x
(x)
<U1
'a' 'b'
array(['a', 'b'], dtype='<U1')
y
(y)
int64
0 1 2
PandasIndex
PandasIndex(Index(['a', 'b'], dtype='object', name='x'))
PandasIndex
PandasIndex(Index([0, 1, 2], dtype='int64', name='y'))
As elsewhere in xarray, an ellipsis (…) can be used to represent all unlisted dimensions:
stacked = array.stack(z=[..., "x"]) stacked
<xarray.DataArray (z: 6)> Size: 48B array([ 0.4691123 , -1.13563237, -0.28286334, 1.21211203, -1.5090585 , -0.17321465]) Coordinates: * z (z) object 48B MultiIndex * y (z) int64 48B 0 0 1 1 2 2 * x (z) <U1 24B 'a' 'b' 'a' 'b' 'a' 'b'
0.4691 -1.136 -0.2829 1.212 -1.509 -0.1732
array([ 0.4691123 , -1.13563237, -0.28286334, 1.21211203, -1.5090585 , -0.17321465])
z
(z)
object
MultiIndex
[6 values with dtype=object]
y
(z)
int64
0 0 1 1 2 2
[6 values with dtype=int64]
x
(z)
<U1
'a' 'b' 'a' 'b' 'a' 'b'
[6 values with dtype=<U1]
PandasMultiIndex
PandasIndex(MultiIndex([(0, 'a'), (0, 'b'), (1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')], name='z'))
These methods are modeled on the pandas.DataFrame
methods of the same name, although in xarray they always create new dimensions rather than adding to the existing index or columns.
Like DataFrame.unstack
, xarray’s unstack
always succeeds, even if the multi-index being unstacked does not contain all possible levels. Missing levels are filled in with NaN
in the resulting object:
stacked2 = stacked[::2] stacked2
<xarray.DataArray (z: 3)> Size: 24B array([ 0.4691123 , -0.28286334, -1.5090585 ]) Coordinates: * z (z) object 24B MultiIndex * y (z) int64 24B 0 1 2 * x (z) <U1 12B 'a' 'a' 'a'
0.4691 -0.2829 -1.509
array([ 0.4691123 , -0.28286334, -1.5090585 ])
z
(z)
object
MultiIndex
[3 values with dtype=object]
y
(z)
int64
0 1 2
[3 values with dtype=int64]
x
(z)
<U1
'a' 'a' 'a'
[3 values with dtype=<U1]
PandasMultiIndex
PandasIndex(MultiIndex([(0, 'a'), (1, 'a'), (2, 'a')], name='z'))
<xarray.DataArray (y: 3, x: 1)> Size: 24B array([[ 0.4691123 ], [-0.28286334], [-1.5090585 ]]) Coordinates: * y (y) int64 24B 0 1 2 * x (x) <U1 4B 'a'
0.4691 -0.2829 -1.509
array([[ 0.4691123 ], [-0.28286334], [-1.5090585 ]])
y
(y)
int64
0 1 2
x
(x)
<U1
'a'
array(['a'], dtype='<U1')
PandasIndex
PandasIndex(Index([0, 1, 2], dtype='int64', name='y'))
PandasIndex
PandasIndex(Index(['a'], dtype='object', name='x'))
However, xarray’s stack
has an important difference from pandas: unlike pandas, it does not automatically drop missing values. Compare:
array = xr.DataArray([[np.nan, 1], [2, 3]], dims=["x", "y"]) array.stack(z=("x", "y"))
<xarray.DataArray (z: 4)> Size: 32B array([nan, 1., 2., 3.]) Coordinates: * z (z) object 32B MultiIndex * x (z) int64 32B 0 0 1 1 * y (z) int64 32B 0 1 0 1
z
(z)
object
MultiIndex
[4 values with dtype=object]
x
(z)
int64
0 0 1 1
[4 values with dtype=int64]
y
(z)
int64
0 1 0 1
[4 values with dtype=int64]
PandasMultiIndex
PandasIndex(MultiIndex([(0, 0), (0, 1), (1, 0), (1, 1)], name='z'))
array.to_pandas().stack()
x y 0 1 1.0 1 0 2.0 1 3.0 dtype: float64
We departed from pandas’s behavior here because predictable shapes for new array dimensions is necessary for Parallel Computing with Dask.
Stacking different variables together#These stacking and unstacking operations are particularly useful for reshaping xarray objects for use in machine learning packages, such as scikit-learn, that usually require two-dimensional numpy arrays as inputs. For datasets with only one variable, we only need stack
and unstack
, but combining multiple variables in a xarray.Dataset
is more complicated. If the variables in the dataset have matching numbers of dimensions, we can call to_dataarray()
and then stack along the the new coordinate. But to_dataarray()
will broadcast the dataarrays together, which will effectively tile the lower dimensional variable along the missing dimensions. The method xarray.Dataset.to_stacked_array()
allows combining variables of differing dimensions without this wasteful copying while xarray.DataArray.to_unstacked_dataset()
reverses this operation. Just as with xarray.Dataset.stack()
the stacked coordinate is represented by a pandas.MultiIndex
object. These methods are used like this:
data = xr.Dataset( data_vars={"a": (("x", "y"), [[0, 1, 2], [3, 4, 5]]), "b": ("x", [6, 7])}, coords={"y": ["u", "v", "w"]}, ) data
<xarray.Dataset> Size: 76B Dimensions: (x: 2, y: 3) Coordinates: * y (y) <U1 12B 'u' 'v' 'w' Dimensions without coordinates: x Data variables: a (x, y) int64 48B 0 1 2 3 4 5 b (x) int64 16B 6 7
y
(y)
<U1
'u' 'v' 'w'
array(['u', 'v', 'w'], dtype='<U1')
a
(x, y)
int64
0 1 2 3 4 5
array([[0, 1, 2], [3, 4, 5]])
b
(x)
int64
6 7
PandasIndex
PandasIndex(Index(['u', 'v', 'w'], dtype='object', name='y'))
stacked = data.to_stacked_array("z", sample_dims=["x"]) stacked
<xarray.DataArray 'a' (x: 2, z: 4)> Size: 64B array([[0, 1, 2, 6], [3, 4, 5, 7]]) Coordinates: * z (z) object 32B MultiIndex * variable (z) <U1 16B 'a' 'a' 'a' 'b' * y (z) object 32B 'u' 'v' 'w' nan Dimensions without coordinates: x
0 1 2 6 3 4 5 7
array([[0, 1, 2, 6], [3, 4, 5, 7]])
z
(z)
object
MultiIndex
[4 values with dtype=object]
variable
(z)
<U1
'a' 'a' 'a' 'b'
[4 values with dtype=<U1]
y
(z)
object
'u' 'v' 'w' nan
[4 values with dtype=object]
PandasMultiIndex
PandasIndex(MultiIndex([('a', 'u'), ('a', 'v'), ('a', 'w'), ('b', nan)], name='z'))
unstacked = stacked.to_unstacked_dataset("z") unstacked
<xarray.Dataset> Size: 88B Dimensions: (y: 3, x: 2) Coordinates: * y (y) object 24B 'u' 'v' 'w' Dimensions without coordinates: x Data variables: a (x, y) int64 48B 0 1 2 3 4 5 b (x) int64 16B 6 7
y
(y)
object
'u' 'v' 'w'
array(['u', 'v', 'w'], dtype=object)
a
(x, y)
int64
0 1 2 3 4 5
array([[0, 1, 2], [3, 4, 5]])
b
(x)
int64
6 7
PandasIndex
PandasIndex(Index(['u', 'v', 'w'], dtype='object', name='y'))
In this example, stacked
is a two dimensional array that we can easily pass to a scikit-learn or another generic numerical method.
Note
Unlike with stack
, in to_stacked_array
, the user specifies the dimensions they do not want stacked. For a machine learning task, these unstacked dimensions can be interpreted as the dimensions over which samples are drawn, whereas the stacked coordinates are the features. Naturally, all variables should possess these sampling dimensions.
Complementary to stack / unstack, xarray’s .set_index
, .reset_index
and .reorder_levels
allow easy manipulation of DataArray
or Dataset
multi-indexes without modifying the data and its dimensions.
You can create a multi-index from several 1-dimensional variables and/or coordinates using set_index()
:
da = xr.DataArray( np.random.rand(4), coords={ "band": ("x", ["a", "a", "b", "b"]), "wavenumber": ("x", np.linspace(200, 400, 4)), }, dims="x", ) da
<xarray.DataArray (x: 4)> Size: 32B array([0.12310214, 0.5430262 , 0.37301223, 0.44799682]) Coordinates: band (x) <U1 16B 'a' 'a' 'b' 'b' wavenumber (x) float64 32B 200.0 266.7 333.3 400.0 Dimensions without coordinates: x
0.1231 0.543 0.373 0.448
array([0.12310214, 0.5430262 , 0.37301223, 0.44799682])
band
(x)
<U1
'a' 'a' 'b' 'b'
array(['a', 'a', 'b', 'b'], dtype='<U1')
wavenumber
(x)
float64
200.0 266.7 333.3 400.0
array([200. , 266.66666667, 333.33333333, 400. ])
mda = da.set_index(x=["band", "wavenumber"]) mda
<xarray.DataArray (x: 4)> Size: 32B array([0.12310214, 0.5430262 , 0.37301223, 0.44799682]) Coordinates: * x (x) object 32B MultiIndex * band (x) <U1 16B 'a' 'a' 'b' 'b' * wavenumber (x) float64 32B 200.0 266.7 333.3 400.0
0.1231 0.543 0.373 0.448
array([0.12310214, 0.5430262 , 0.37301223, 0.44799682])
x
(x)
object
MultiIndex
[4 values with dtype=object]
band
(x)
<U1
'a' 'a' 'b' 'b'
[4 values with dtype=<U1]
wavenumber
(x)
float64
200.0 266.7 333.3 400.0
[4 values with dtype=float64]
PandasMultiIndex
PandasIndex(MultiIndex([('a', 200.0), ('a', 266.6666666666667), ('b', 333.33333333333337), ('b', 400.0)], name='x'))
These coordinates can now be used for indexing, e.g.,
<xarray.DataArray (wavenumber: 2)> Size: 16B array([0.12310214, 0.5430262 ]) Coordinates: * wavenumber (wavenumber) float64 16B 200.0 266.7 band <U1 4B 'a'
0.1231 0.543
array([0.12310214, 0.5430262 ])
wavenumber
(wavenumber)
float64
200.0 266.7
array([200. , 266.666667])
band
()
<U1
'a'
PandasIndex
PandasIndex(Index([200.0, 266.6666666666667], dtype='float64', name='wavenumber'))
Conversely, you can use reset_index()
to extract multi-index levels as coordinates (this is mainly useful for serialization):
<xarray.DataArray (x: 4)> Size: 32B array([0.12310214, 0.5430262 , 0.37301223, 0.44799682]) Coordinates: band (x) <U1 16B 'a' 'a' 'b' 'b' wavenumber (x) float64 32B 200.0 266.7 333.3 400.0 Dimensions without coordinates: x
0.1231 0.543 0.373 0.448
array([0.12310214, 0.5430262 , 0.37301223, 0.44799682])
band
(x)
<U1
'a' 'a' 'b' 'b'
[4 values with dtype=<U1]
wavenumber
(x)
float64
200.0 266.7 333.3 400.0
[4 values with dtype=float64]
reorder_levels()
allows changing the order of multi-index levels:
mda.reorder_levels(x=["wavenumber", "band"])
<xarray.DataArray (x: 4)> Size: 32B array([0.12310214, 0.5430262 , 0.37301223, 0.44799682]) Coordinates: * x (x) object 32B MultiIndex * wavenumber (x) float64 32B 200.0 266.7 333.3 400.0 * band (x) <U1 16B 'a' 'a' 'b' 'b'
0.1231 0.543 0.373 0.448
array([0.12310214, 0.5430262 , 0.37301223, 0.44799682])
x
(x)
object
MultiIndex
[4 values with dtype=object]
wavenumber
(x)
float64
200.0 266.7 333.3 400.0
[4 values with dtype=float64]
band
(x)
<U1
'a' 'a' 'b' 'b'
[4 values with dtype=<U1]
PandasMultiIndex
PandasIndex(MultiIndex([( 200.0, 'a'), ( 266.6666666666667, 'a'), (333.33333333333337, 'b'), ( 400.0, 'b')], name='x'))
As of xarray v0.9 coordinate labels for each dimension are optional. You can also use .set_index
/ .reset_index
to add / remove labels for one or several dimensions:
array = xr.DataArray([1, 2, 3], dims="x") array
<xarray.DataArray (x: 3)> Size: 24B array([1, 2, 3]) Dimensions without coordinates: x
array["c"] = ("x", ["a", "b", "c"]) array.set_index(x="c")
<xarray.DataArray (x: 3)> Size: 24B array([1, 2, 3]) Coordinates: * x (x) <U1 12B 'a' 'b' 'c'
x
(x)
<U1
'a' 'b' 'c'
array(['a', 'b', 'c'], dtype='<U1')
PandasIndex
PandasIndex(Index(['a', 'b', 'c'], dtype='object', name='x'))
array = array.set_index(x="c") array = array.reset_index("x", drop=True)Shift and roll#
To adjust coordinate labels, you can use the shift()
and roll()
methods:
array = xr.DataArray([1, 2, 3, 4], dims="x") array.shift(x=2)
<xarray.DataArray (x: 4)> Size: 32B array([nan, nan, 1., 2.]) Dimensions without coordinates: x
nan nan 1.0 2.0
array([nan, nan, 1., 2.])
array.roll(x=2, roll_coords=True)
<xarray.DataArray (x: 4)> Size: 32B array([3, 4, 1, 2]) Dimensions without coordinates: x
One may sort a DataArray/Dataset via sortby()
and sortby()
. The input can be an individual or list of 1D DataArray
objects:
ds = xr.Dataset( { "A": (("x", "y"), [[1, 2], [3, 4]]), "B": (("x", "y"), [[5, 6], [7, 8]]), }, coords={"x": ["b", "a"], "y": [1, 0]}, ) dax = xr.DataArray([100, 99], [("x", [0, 1])]) day = xr.DataArray([90, 80], [("y", [0, 1])]) ds.sortby([day, dax])
<xarray.Dataset> Size: 88B Dimensions: (x: 2, y: 2) Coordinates: * x (x) <U1 8B 'b' 'a' * y (y) int64 16B 1 0 Data variables: A (x, y) int64 32B 1 2 3 4 B (x, y) int64 32B 5 6 7 8
x
(x)
<U1
'b' 'a'
array(['b', 'a'], dtype='<U1')
y
(y)
int64
1 0
A
(x, y)
int64
1 2 3 4
B
(x, y)
int64
5 6 7 8
PandasIndex
PandasIndex(Index(['b', 'a'], dtype='object', name='x'))
PandasIndex
PandasIndex(Index([1, 0], dtype='int64', name='y'))
As a shortcut, you can refer to existing coordinates by name:
<xarray.Dataset> Size: 88B Dimensions: (x: 2, y: 2) Coordinates: * x (x) <U1 8B 'a' 'b' * y (y) int64 16B 1 0 Data variables: A (x, y) int64 32B 3 4 1 2 B (x, y) int64 32B 7 8 5 6
x
(x)
<U1
'a' 'b'
array(['a', 'b'], dtype='<U1')
y
(y)
int64
1 0
A
(x, y)
int64
3 4 1 2
B
(x, y)
int64
7 8 5 6
PandasIndex
PandasIndex(Index(['a', 'b'], dtype='object', name='x'))
PandasIndex
PandasIndex(Index([1, 0], dtype='int64', name='y'))
<xarray.Dataset> Size: 88B Dimensions: (x: 2, y: 2) Coordinates: * x (x) <U1 8B 'a' 'b' * y (y) int64 16B 0 1 Data variables: A (x, y) int64 32B 4 3 2 1 B (x, y) int64 32B 8 7 6 5
x
(x)
<U1
'a' 'b'
array(['a', 'b'], dtype='<U1')
y
(y)
int64
0 1
A
(x, y)
int64
4 3 2 1
B
(x, y)
int64
8 7 6 5
PandasIndex
PandasIndex(Index(['a', 'b'], dtype='object', name='x'))
PandasIndex
PandasIndex(Index([0, 1], dtype='int64', name='y'))
ds.sortby(["y", "x"], ascending=False)
<xarray.Dataset> Size: 88B Dimensions: (x: 2, y: 2) Coordinates: * x (x) <U1 8B 'b' 'a' * y (y) int64 16B 1 0 Data variables: A (x, y) int64 32B 1 2 3 4 B (x, y) int64 32B 5 6 7 8
x
(x)
<U1
'b' 'a'
array(['b', 'a'], dtype='<U1')
y
(y)
int64
1 0
A
(x, y)
int64
1 2 3 4
B
(x, y)
int64
5 6 7 8
PandasIndex
PandasIndex(Index(['b', 'a'], dtype='object', name='x'))
PandasIndex
PandasIndex(Index([1, 0], dtype='int64', name='y'))
Whilst coarsen
is normally used for reducing your data’s resolution by applying a reduction function (see the page on computation), it can also be used to reorganise your data without applying a computation via construct()
.
Taking our example tutorial air temperature dataset over the Northern US
air = xr.tutorial.open_dataset("air_temperature")["air"] air.isel(time=0).plot(x="lon", y="lat");
we can split this up into sub-regions of size (9, 18)
points using construct()
:
regions = air.coarsen(lat=9, lon=18, boundary="pad").construct( lon=("x_coarse", "x_fine"), lat=("y_coarse", "y_fine") ) with xr.set_options(display_expand_data=False): regions
9 new regions have been created, each of size 9 by 18 points. The boundary="pad"
kwarg ensured that all regions are the same size even though the data does not evenly divide into these sizes.
By plotting these 9 regions together via faceting we can see how they relate to the original data.
regions.isel(time=0).plot( x="x_fine", y="y_fine", col="x_coarse", row="y_coarse", yincrease=False );
We are now free to easily apply any custom computation to each coarsened region of our new dataarray. This would involve specifying that applied functions should act over the "x_fine"
and "y_fine"
dimensions, but broadcast over the "x_coarse"
and "y_coarse"
dimensions.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4