1
+ """
2
+ Xarray : Quick tour
3
+ ===================
4
+
5
+ Basically, this example gives a very small introduction to Xarray (very small).
6
+ We illustrate how to define a DataArray container, access its components,
7
+ perform some of the basic operations and slicing / indexing.
8
+ """
9
+ import numpy as np
10
+ import xarray as xr
11
+ import pandas as pd
12
+
13
+ ###############################################################################
14
+ # Simulate data
15
+ # -------------
16
+ #
17
+ # lets start by creating a random spatio-temporal array
18
+
19
+ n_times = 30
20
+ n_roi = 7
21
+ times_vec = np .linspace (- 1 , 1 , n_times )
22
+ roi_vec = np .array ([f"roi_{ k } " for k in range (n_roi )])
23
+ np_data = np .random .rand (n_times , n_roi )
24
+ print (np_data .shape )
25
+ print ('*' * 79 )
26
+
27
+ ###############################################################################
28
+ # Xarray conversion and access to the internal components
29
+ # -------------------------------------------------------
30
+ #
31
+ # A DataArray is a container (like a well known numpy array) except that you
32
+ # can add a label to each coordinate. To this end, the input `dims` is a tuple
33
+ # that describes the dimension names and `coords` describes the value along
34
+ # this coordinate
35
+
36
+ # let's convert it to a DataArray
37
+ da_data = xr .DataArray (np_data , dims = ('times' , 'roi' ),
38
+ coords = (times_vec , roi_vec ))
39
+ print (da_data .shape )
40
+ print (da_data )
41
+ print ('*' * 79 )
42
+
43
+ # if you want to get the dimension names and values
44
+ print (f'Dimension names : { da_data .dims } ' )
45
+ print (f'Dimension values : { da_data .coords } ' )
46
+ print (f"Data of a specific dimension : { da_data .roi .data } " )
47
+ print ('*' * 79 )
48
+
49
+ # if you want to get the original NumPy array enter the following :
50
+ da_data .data
51
+
52
+ # if you want to change the values of a coordinate
53
+ da_data ['roi' ] = np .array ([f"roi_{ k % 3 } " for k in range (n_roi )])
54
+ print (f"New ROI names : { da_data .roi .data } " )
55
+ print ('*' * 79 )
56
+
57
+ # if you need to compute or get the min / max / mean across a specific
58
+ # dimension
59
+ da_data .min ('times' ) # minimum across time points
60
+ da_data .max ('times' ) # maximum across time points
61
+ da_data .mean ('roi' ) # mean across all ROI
62
+
63
+ # similarly to Pandas, it's also possible to group along a dimension and then
64
+ # take the mean. For example, here's how to group and mean by roi names
65
+ da_m = da_data .groupby ('roi' ).mean ('roi' )
66
+ print (da_m )
67
+ print ('*' * 79 )
68
+
69
+
70
+ ###############################################################################
71
+ # Xarray slicing and indexing
72
+ # ---------------------------
73
+ #
74
+ # Now we show how to slice the container
75
+
76
+ # select a single specific ROI based on it's name
77
+ da_data .sel (roi = 'roi_0' )
78
+
79
+ # select a time range
80
+ da_time_slice = da_data .sel (times = slice (- .5 , .5 ))
81
+ print (f"Temporal selection : { da_time_slice .coords } " )
82
+ print ('*' * 79 )
83
+
84
+ # off course, spatio-temporal selection is also supported
85
+ da_st = da_data .sel (times = slice (- .5 , .5 ), roi = 'roi_1' )
86
+ print (f"Spatio-temporal selection : { da_st .coords } " )
87
+ print ('*' * 79 )
88
+
89
+ # you can also slice according to indices
90
+ da_isel = da_data .isel (times = slice (10 , 20 ))
91
+ print (f"Integer selection : { da_isel .coords } " )
92
+ print ('*' * 79 )
93
+
94
+ # however, if you want for example select multiple items based on their names,
95
+ # you have to use booleans. Here's a small example that's using Pandas
96
+ roi = da_data .roi .data
97
+ use_roi = ['roi_0' , 'roi_2' ]
98
+ is_roi = pd .Series (roi ).str .contains ('|' .join (use_roi ))
99
+ da_mi = da_data .isel (roi = is_roi )
100
+ print (f"Multi-items selection : { da_mi .coords } " )
101
+
102
+ ###############################################################################
103
+ # Xarray attributes
104
+ # -----------------
105
+ #
106
+ # One of the nice features of DataArray is that it supporting setting
107
+ # attributes. Therefore you can add, for example, the parameters that describe
108
+ # your analysis
109
+
110
+ # adding a few string attributes
111
+ da_data .attrs ['inference' ] = 'ffx'
112
+ da_data .attrs ['stats' ] = 'cluster-based'
113
+ da_data .attrs ['description' ] = """Here's a small description of the analysis
114
+ I'm currently running. Trying to find a difference between condition 1. vs 2.
115
+ """
116
+
117
+ # you can also add vectors (but not arrays) to the attributes
118
+ da_data .attrs ['vector' ] = np .arange (30 )
119
+
120
+ # however, "None" seems to pose a problem when saving the results. Therefore,
121
+ # one quick way to solve this is simply to convert it into a string
122
+ da_data .attrs ['none_problem' ] = str (None )
123
+
124
+ print (da_data )
125
+
126
+ ###############################################################################
127
+ # Xarray to an other format
128
+ # -------------------------
129
+ #
130
+ # Finally, we quickly illustrate how to convert a DataArray into, for example,
131
+ # a pandas.DataFrame
132
+
133
+ print (da_data .to_pandas ())
0 commit comments