Time series data#

A major use case for xarray is multi-dimensional time-series data. Accordingly, we’ve copied many of features that make working with time-series data in pandas such a joy to xarray. In most cases, we rely on pandas for the core functionality.

Creating datetime64 data#

Xarray uses the numpy dtypes numpy.datetime64 and numpy.timedelta64 with specified units (one of "s", "ms", "us" and "ns") to represent datetime data, which offer vectorized operations with numpy and smooth integration with pandas.

To convert to or create regular arrays of numpy.datetime64 data, we recommend using pandas.to_datetime(), pandas.DatetimeIndex, or xarray.date_range():

pd.to_datetime(["2000年01月01日", "2000年02月02日"])
DatetimeIndex(['2000年01月01日', '2000年02月02日'], dtype='datetime64[us]', freq=None)
pd.DatetimeIndex(
 ["2000年01月01日 00:00:00", "2000年02月02日 00:00:00"], dtype="datetime64[s]"
)
DatetimeIndex(['2000年01月01日', '2000年02月02日'], dtype='datetime64[s]', freq=None)
xr.date_range("2000年01月01日", periods=365)
DatetimeIndex(['2000年01月01日', '2000年01月02日', '2000年01月03日', '2000年01月04日',
 '2000年01月05日', '2000年01月06日', '2000年01月07日', '2000年01月08日',
 '2000年01月09日', '2000年01月10日',
 ...
 '2000年12月21日', '2000年12月22日', '2000年12月23日', '2000年12月24日',
 '2000年12月25日', '2000年12月26日', '2000年12月27日', '2000年12月28日',
 '2000年12月29日', '2000年12月30日'],
 dtype='datetime64[ns]', length=365, freq='D')
xr.date_range("2000年01月01日", periods=365, unit="s")
DatetimeIndex(['2000年01月01日', '2000年01月02日', '2000年01月03日', '2000年01月04日',
 '2000年01月05日', '2000年01月06日', '2000年01月07日', '2000年01月08日',
 '2000年01月09日', '2000年01月10日',
 ...
 '2000年12月21日', '2000年12月22日', '2000年12月23日', '2000年12月24日',
 '2000年12月25日', '2000年12月26日', '2000年12月27日', '2000年12月28日',
 '2000年12月29日', '2000年12月30日'],
 dtype='datetime64[s]', length=365, freq='D')

Note

Care has to be taken to create the output with the wanted resolution. For pandas.date_range() the unit-kwarg has to be specified and for pandas.to_datetime() the selection of the resolution isn’t possible at all. For that pd.DatetimeIndex can be used directly. There is more in-depth information in section Time Coding.

Alternatively, you can supply arrays of Python datetime objects. These get converted automatically when used as arguments in xarray objects (with us-resolution):

importdatetime
xr.Dataset({"time": datetime.datetime(2000, 1, 1)})
<xarray.Dataset> Size: 8B
Dimensions: ()
Data variables:
 time datetime64[us] 8B 2000年01月01日
xarray.Dataset
    • time
      ()
      datetime64[us]
      2000年01月01日
      array('2000年01月01日T00:00:00.000000', dtype='datetime64[us]')

When reading or writing netCDF files, xarray automatically decodes datetime and timedelta arrays using CF conventions (that is, by using a units attribute like 'days since 2000年01月01日').

Note

When decoding/encoding datetimes for non-standard calendars or for dates before 1582年10月15日, xarray uses the cftime library by default. It was previously packaged with the netcdf4-python package under the name netcdftime but is now distributed separately. cftime is an optional dependency of xarray.

You can manual decode arrays in this form by passing a dataset to decode_cf():

attrs = {"units": "hours since 2000年01月01日"}
ds = xr.Dataset({"time": ("time", [0, 1, 2, 3], attrs)})
# Default decoding to 'ns'-resolution
xr.decode_cf(ds)
<xarray.Dataset> Size: 32B
Dimensions: (time: 4)
Coordinates:
 * time (time) datetime64[ns] 32B 2000年01月01日 ... 2000年01月01日T03:00:00
Data variables:
 *empty*
xarray.Dataset
    • time: 4
    • time
      (time)
      datetime64[ns]
      2000年01月01日 ... 2000年01月01日T03:00:00
      array(['2000年01月01日T00:00:00.000000000', '2000年01月01日T01:00:00.000000000',
       '2000年01月01日T02:00:00.000000000', '2000年01月01日T03:00:00.000000000'],
       dtype='datetime64[ns]')
# Decoding to 's'-resolution
coder = xr.coders.CFDatetimeCoder(time_unit="s")
xr.decode_cf(ds, decode_times=coder)
<xarray.Dataset> Size: 32B
Dimensions: (time: 4)
Coordinates:
 * time (time) datetime64[s] 32B 2000年01月01日 ... 2000年01月01日T03:00:00
Data variables:
 *empty*
xarray.Dataset
    • time: 4
    • time
      (time)
      datetime64[s]
      2000年01月01日 ... 2000年01月01日T03:00:00
      array(['2000年01月01日T00:00:00', '2000年01月01日T01:00:00', '2000年01月01日T02:00:00',
       '2000年01月01日T03:00:00'], dtype='datetime64[s]')

From xarray 2025年01月2日 the resolution of the dates can be one of "s", "ms", "us" or "ns". One limitation of using datetime64[ns] is that it limits the native representation of dates to those that fall between the years 1678 and 2262, which gets increased significantly with lower resolutions. When a store contains dates outside of these bounds (or dates < 1582年10月15日 with a Gregorian, also known as standard, calendar), dates will be returned as arrays of cftime.datetime objects and a CFTimeIndex will be used for indexing. CFTimeIndex enables most of the indexing functionality of a pandas.DatetimeIndex. See Non-standard calendars and dates outside the precision range for more information.

Datetime indexing#

Xarray borrows powerful indexing machinery from pandas (see Indexing and selecting data).

This allows for several useful and succinct forms of indexing, particularly for datetime64 data. For example, we support indexing with strings for single items and with the slice object:

time = pd.date_range("2000年01月01日", freq="h", periods=365 * 24)
ds = xr.Dataset({"foo": ("time", np.arange(365 * 24)), "time": time})
ds.sel(time="2000-01")
<xarray.Dataset> Size: 12kB
Dimensions: (time: 744)
Coordinates:
 * time (time) datetime64[us] 6kB 2000年01月01日 ... 2000年01月31日T23:00:00
Data variables:
 foo (time) int64 6kB 0 1 2 3 4 5 6 7 ... 737 738 739 740 741 742 743
xarray.Dataset
    • time: 744
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年01月31日T23:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T01:00:00.000000',
       '2000年01月01日T02:00:00.000000', ..., '2000年01月31日T21:00:00.000000',
       '2000年01月31日T22:00:00.000000', '2000年01月31日T23:00:00.000000'],
       shape=(744,), dtype='datetime64[us]')
    • foo
      (time)
      int64
      0 1 2 3 4 5 ... 739 740 741 742 743
      array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
       26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
       39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
       91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
       117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
       130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
       143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
       156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
       169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
       182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
       195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
       208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
       221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
       234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
       247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
      ...
       494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506,
       507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519,
       520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
       533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545,
       546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558,
       559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571,
       572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584,
       585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597,
       598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610,
       611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623,
       624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636,
       637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649,
       650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662,
       663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675,
       676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688,
       689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
       702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714,
       715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727,
       728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740,
       741, 742, 743])
ds.sel(time=slice("2000年06月01日", "2000年06月10日"))
<xarray.Dataset> Size: 4kB
Dimensions: (time: 240)
Coordinates:
 * time (time) datetime64[us] 2kB 2000年06月01日 ... 2000年06月10日T23:00:00
Data variables:
 foo (time) int64 2kB 3648 3649 3650 3651 3652 ... 3884 3885 3886 3887
xarray.Dataset
    • time: 240
    • time
      (time)
      datetime64[us]
      2000年06月01日 ... 2000年06月10日T23:00:00
      array(['2000年06月01日T00:00:00.000000', '2000年06月01日T01:00:00.000000',
       '2000年06月01日T02:00:00.000000', ..., '2000年06月10日T21:00:00.000000',
       '2000年06月10日T22:00:00.000000', '2000年06月10日T23:00:00.000000'],
       shape=(240,), dtype='datetime64[us]')
    • foo
      (time)
      int64
      3648 3649 3650 ... 3885 3886 3887
      array([3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658,
       3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669,
       3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680,
       3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691,
       3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702,
       3703, 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713,
       3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724,
       3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735,
       3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746,
       3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757,
       3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768,
       3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779,
       3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790,
       3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801,
       3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812,
       3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823,
       3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834,
       3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845,
       3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856,
       3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867,
       3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878,
       3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887])

You can also select a particular time by indexing with a datetime.time object:

ds.sel(time=datetime.time(12))
<xarray.Dataset> Size: 6kB
Dimensions: (time: 365)
Coordinates:
 * time (time) datetime64[us] 3kB 2000年01月01日T12:00:00 ... 2000年12月30日T12:...
Data variables:
 foo (time) int64 3kB 12 36 60 84 108 132 ... 8652 8676 8700 8724 8748
xarray.Dataset
    • time: 365
    • time
      (time)
      datetime64[us]
      2000年01月01日T12:00:00 ... 2000-12-...
      array(['2000年01月01日T12:00:00.000000', '2000年01月02日T12:00:00.000000',
       '2000年01月03日T12:00:00.000000', ..., '2000年12月28日T12:00:00.000000',
       '2000年12月29日T12:00:00.000000', '2000年12月30日T12:00:00.000000'],
       shape=(365,), dtype='datetime64[us]')
    • foo
      (time)
      int64
      12 36 60 84 ... 8676 8700 8724 8748
      array([ 12, 36, 60, 84, 108, 132, 156, 180, 204, 228, 252,
       276, 300, 324, 348, 372, 396, 420, 444, 468, 492, 516,
       540, 564, 588, 612, 636, 660, 684, 708, 732, 756, 780,
       804, 828, 852, 876, 900, 924, 948, 972, 996, 1020, 1044,
       1068, 1092, 1116, 1140, 1164, 1188, 1212, 1236, 1260, 1284, 1308,
       1332, 1356, 1380, 1404, 1428, 1452, 1476, 1500, 1524, 1548, 1572,
       1596, 1620, 1644, 1668, 1692, 1716, 1740, 1764, 1788, 1812, 1836,
       1860, 1884, 1908, 1932, 1956, 1980, 2004, 2028, 2052, 2076, 2100,
       2124, 2148, 2172, 2196, 2220, 2244, 2268, 2292, 2316, 2340, 2364,
       2388, 2412, 2436, 2460, 2484, 2508, 2532, 2556, 2580, 2604, 2628,
       2652, 2676, 2700, 2724, 2748, 2772, 2796, 2820, 2844, 2868, 2892,
       2916, 2940, 2964, 2988, 3012, 3036, 3060, 3084, 3108, 3132, 3156,
       3180, 3204, 3228, 3252, 3276, 3300, 3324, 3348, 3372, 3396, 3420,
       3444, 3468, 3492, 3516, 3540, 3564, 3588, 3612, 3636, 3660, 3684,
       3708, 3732, 3756, 3780, 3804, 3828, 3852, 3876, 3900, 3924, 3948,
       3972, 3996, 4020, 4044, 4068, 4092, 4116, 4140, 4164, 4188, 4212,
       4236, 4260, 4284, 4308, 4332, 4356, 4380, 4404, 4428, 4452, 4476,
       4500, 4524, 4548, 4572, 4596, 4620, 4644, 4668, 4692, 4716, 4740,
       4764, 4788, 4812, 4836, 4860, 4884, 4908, 4932, 4956, 4980, 5004,
       5028, 5052, 5076, 5100, 5124, 5148, 5172, 5196, 5220, 5244, 5268,
       5292, 5316, 5340, 5364, 5388, 5412, 5436, 5460, 5484, 5508, 5532,
       5556, 5580, 5604, 5628, 5652, 5676, 5700, 5724, 5748, 5772, 5796,
       5820, 5844, 5868, 5892, 5916, 5940, 5964, 5988, 6012, 6036, 6060,
       6084, 6108, 6132, 6156, 6180, 6204, 6228, 6252, 6276, 6300, 6324,
       6348, 6372, 6396, 6420, 6444, 6468, 6492, 6516, 6540, 6564, 6588,
       6612, 6636, 6660, 6684, 6708, 6732, 6756, 6780, 6804, 6828, 6852,
       6876, 6900, 6924, 6948, 6972, 6996, 7020, 7044, 7068, 7092, 7116,
       7140, 7164, 7188, 7212, 7236, 7260, 7284, 7308, 7332, 7356, 7380,
       7404, 7428, 7452, 7476, 7500, 7524, 7548, 7572, 7596, 7620, 7644,
       7668, 7692, 7716, 7740, 7764, 7788, 7812, 7836, 7860, 7884, 7908,
       7932, 7956, 7980, 8004, 8028, 8052, 8076, 8100, 8124, 8148, 8172,
       8196, 8220, 8244, 8268, 8292, 8316, 8340, 8364, 8388, 8412, 8436,
       8460, 8484, 8508, 8532, 8556, 8580, 8604, 8628, 8652, 8676, 8700,
       8724, 8748])

For more details, read the pandas documentation and the section on Indexing Using Datetime Components (i.e. using the .dt accessor).

Datetime components#

Similar to pandas accessors, the components of datetime objects contained in a given DataArray can be quickly computed using a special .dt accessor.

time = pd.date_range("2000年01月01日", freq="6h", periods=365 * 4)
ds = xr.Dataset({"foo": ("time", np.arange(365 * 4)), "time": time})
ds.time.dt.hour
<xarray.DataArray 'hour' (time: 1460)> Size: 12kB
array([ 0, 6, 12, ..., 6, 12, 18], shape=(1460,))
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'hour'
  • time: 1460
  • 0 6 12 18 0 6 12 18 0 6 12 18 0 6 ... 18 0 6 12 18 0 6 12 18 0 6 12 18
    array([ 0, 6, 12, ..., 6, 12, 18], shape=(1460,))
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
ds.time.dt.dayofweek
<xarray.DataArray 'dayofweek' (time: 1460)> Size: 12kB
array([5, 5, 5, ..., 5, 5, 5], shape=(1460,))
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'dayofweek'
  • time: 1460
  • 5 5 5 5 6 6 6 6 0 0 0 0 1 1 1 1 2 ... 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5
    array([5, 5, 5, ..., 5, 5, 5], shape=(1460,))
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')

The .dt accessor works on both coordinate dimensions as well as multi-dimensional data.

Xarray also supports a notion of "virtual" or "derived" coordinates for datetime components implemented by pandas, including "year", "month", "day", "hour", "minute", "second", "dayofyear", "week", "dayofweek", "weekday" and "quarter":

ds["time.month"]
<xarray.DataArray 'month' (time: 1460)> Size: 12kB
array([ 1, 1, 1, ..., 12, 12, 12], shape=(1460,))
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'month'
  • time: 1460
  • 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ... 12 12 12 12 12 12 12 12 12 12 12 12 12
    array([ 1, 1, 1, ..., 12, 12, 12], shape=(1460,))
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
ds["time.dayofyear"]
<xarray.DataArray 'dayofyear' (time: 1460)> Size: 12kB
array([ 1, 1, 1, ..., 365, 365, 365], shape=(1460,))
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'dayofyear'
  • time: 1460
  • 1 1 1 1 2 2 2 2 3 3 3 ... 363 363 363 364 364 364 364 365 365 365 365
    array([ 1, 1, 1, ..., 365, 365, 365], shape=(1460,))
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')

For use as a derived coordinate, xarray adds 'season' to the list of datetime components supported by pandas:

ds["time.season"]
<xarray.DataArray 'season' (time: 1460)> Size: 18kB
array(['DJF', 'DJF', 'DJF', ..., 'DJF', 'DJF', 'DJF'],
 shape=(1460,), dtype='<U3')
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'season'
  • time: 1460
  • 'DJF' 'DJF' 'DJF' 'DJF' 'DJF' 'DJF' ... 'DJF' 'DJF' 'DJF' 'DJF' 'DJF'
    array(['DJF', 'DJF', 'DJF', ..., 'DJF', 'DJF', 'DJF'],
     shape=(1460,), dtype='<U3')
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
ds["time"].dt.season
<xarray.DataArray 'season' (time: 1460)> Size: 18kB
array(['DJF', 'DJF', 'DJF', ..., 'DJF', 'DJF', 'DJF'],
 shape=(1460,), dtype='<U3')
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'season'
  • time: 1460
  • 'DJF' 'DJF' 'DJF' 'DJF' 'DJF' 'DJF' ... 'DJF' 'DJF' 'DJF' 'DJF' 'DJF'
    array(['DJF', 'DJF', 'DJF', ..., 'DJF', 'DJF', 'DJF'],
     shape=(1460,), dtype='<U3')
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')

The set of valid seasons consists of ‘DJF’, ‘MAM’, ‘JJA’ and ‘SON’, labeled by the first letters of the corresponding months.

You can use these shortcuts with both Datasets and DataArray coordinates.

In addition, xarray supports rounding operations floor, ceil, and round. These operations require that you supply a rounding frequency as a string argument.

ds["time"].dt.floor("D")
<xarray.DataArray 'floor' (time: 1460)> Size: 12kB
array(['2000年01月01日T00:00:00.000000', '2000年01月01日T00:00:00.000000',
 '2000年01月01日T00:00:00.000000', ..., '2000年12月30日T00:00:00.000000',
 '2000年12月30日T00:00:00.000000', '2000年12月30日T00:00:00.000000'],
 shape=(1460,), dtype='datetime64[us]')
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'floor'
  • time: 1460
  • 2000年01月01日 2000年01月01日 2000年01月01日 ... 2000年12月30日 2000年12月30日 2000年12月30日
    array(['2000年01月01日T00:00:00.000000', '2000年01月01日T00:00:00.000000',
     '2000年01月01日T00:00:00.000000', ..., '2000年12月30日T00:00:00.000000',
     '2000年12月30日T00:00:00.000000', '2000年12月30日T00:00:00.000000'],
     shape=(1460,), dtype='datetime64[us]')
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')

The .dt accessor can also be used to generate formatted datetime strings for arrays utilising the same formatting as the standard datetime.strftime.

ds["time"].dt.strftime("%a, %b %d %H:%M")
<xarray.DataArray 'strftime' (time: 1460)> Size: 12kB
array(['Sat, Jan 01 00:00', 'Sat, Jan 01 06:00', 'Sat, Jan 01 12:00', ...,
 'Sat, Dec 30 06:00', 'Sat, Dec 30 12:00', 'Sat, Dec 30 18:00'],
 shape=(1460,), dtype=object)
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
xarray.DataArray
'strftime'
  • time: 1460
  • 'Sat, Jan 01 00:00' 'Sat, Jan 01 06:00' ... 'Sat, Dec 30 18:00'
    array(['Sat, Jan 01 00:00', 'Sat, Jan 01 06:00', 'Sat, Jan 01 12:00', ...,
     'Sat, Dec 30 06:00', 'Sat, Dec 30 12:00', 'Sat, Dec 30 18:00'],
     shape=(1460,), dtype=object)
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')

Indexing Using Datetime Components#

You can use use the .dt accessor when subsetting your data as well. For example, we can subset for the month of January using the following:

ds.isel(time=(ds.time.dt.month == 1))
<xarray.Dataset> Size: 2kB
Dimensions: (time: 124)
Coordinates:
 * time (time) datetime64[us] 992B 2000年01月01日 ... 2000年01月31日T18:00:00
Data variables:
 foo (time) int64 992B 0 1 2 3 4 5 6 7 ... 117 118 119 120 121 122 123
xarray.Dataset
    • time: 124
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年01月31日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', '2000年01月01日T18:00:00.000000',
       '2000年01月02日T00:00:00.000000', '2000年01月02日T06:00:00.000000',
       '2000年01月02日T12:00:00.000000', '2000年01月02日T18:00:00.000000',
       '2000年01月03日T00:00:00.000000', '2000年01月03日T06:00:00.000000',
       '2000年01月03日T12:00:00.000000', '2000年01月03日T18:00:00.000000',
       '2000年01月04日T00:00:00.000000', '2000年01月04日T06:00:00.000000',
       '2000年01月04日T12:00:00.000000', '2000年01月04日T18:00:00.000000',
       '2000年01月05日T00:00:00.000000', '2000年01月05日T06:00:00.000000',
       '2000年01月05日T12:00:00.000000', '2000年01月05日T18:00:00.000000',
       '2000年01月06日T00:00:00.000000', '2000年01月06日T06:00:00.000000',
       '2000年01月06日T12:00:00.000000', '2000年01月06日T18:00:00.000000',
       '2000年01月07日T00:00:00.000000', '2000年01月07日T06:00:00.000000',
       '2000年01月07日T12:00:00.000000', '2000年01月07日T18:00:00.000000',
       '2000年01月08日T00:00:00.000000', '2000年01月08日T06:00:00.000000',
       '2000年01月08日T12:00:00.000000', '2000年01月08日T18:00:00.000000',
       '2000年01月09日T00:00:00.000000', '2000年01月09日T06:00:00.000000',
       '2000年01月09日T12:00:00.000000', '2000年01月09日T18:00:00.000000',
       '2000年01月10日T00:00:00.000000', '2000年01月10日T06:00:00.000000',
       '2000年01月10日T12:00:00.000000', '2000年01月10日T18:00:00.000000',
       '2000年01月11日T00:00:00.000000', '2000年01月11日T06:00:00.000000',
       '2000年01月11日T12:00:00.000000', '2000年01月11日T18:00:00.000000',
       '2000年01月12日T00:00:00.000000', '2000年01月12日T06:00:00.000000',
       '2000年01月12日T12:00:00.000000', '2000年01月12日T18:00:00.000000',
       '2000年01月13日T00:00:00.000000', '2000年01月13日T06:00:00.000000',
       '2000年01月13日T12:00:00.000000', '2000年01月13日T18:00:00.000000',
       '2000年01月14日T00:00:00.000000', '2000年01月14日T06:00:00.000000',
       '2000年01月14日T12:00:00.000000', '2000年01月14日T18:00:00.000000',
       '2000年01月15日T00:00:00.000000', '2000年01月15日T06:00:00.000000',
       '2000年01月15日T12:00:00.000000', '2000年01月15日T18:00:00.000000',
       '2000年01月16日T00:00:00.000000', '2000年01月16日T06:00:00.000000',
       '2000年01月16日T12:00:00.000000', '2000年01月16日T18:00:00.000000',
       '2000年01月17日T00:00:00.000000', '2000年01月17日T06:00:00.000000',
       '2000年01月17日T12:00:00.000000', '2000年01月17日T18:00:00.000000',
       '2000年01月18日T00:00:00.000000', '2000年01月18日T06:00:00.000000',
       '2000年01月18日T12:00:00.000000', '2000年01月18日T18:00:00.000000',
       '2000年01月19日T00:00:00.000000', '2000年01月19日T06:00:00.000000',
       '2000年01月19日T12:00:00.000000', '2000年01月19日T18:00:00.000000',
       '2000年01月20日T00:00:00.000000', '2000年01月20日T06:00:00.000000',
       '2000年01月20日T12:00:00.000000', '2000年01月20日T18:00:00.000000',
       '2000年01月21日T00:00:00.000000', '2000年01月21日T06:00:00.000000',
       '2000年01月21日T12:00:00.000000', '2000年01月21日T18:00:00.000000',
       '2000年01月22日T00:00:00.000000', '2000年01月22日T06:00:00.000000',
       '2000年01月22日T12:00:00.000000', '2000年01月22日T18:00:00.000000',
       '2000年01月23日T00:00:00.000000', '2000年01月23日T06:00:00.000000',
       '2000年01月23日T12:00:00.000000', '2000年01月23日T18:00:00.000000',
       '2000年01月24日T00:00:00.000000', '2000年01月24日T06:00:00.000000',
       '2000年01月24日T12:00:00.000000', '2000年01月24日T18:00:00.000000',
       '2000年01月25日T00:00:00.000000', '2000年01月25日T06:00:00.000000',
       '2000年01月25日T12:00:00.000000', '2000年01月25日T18:00:00.000000',
       '2000年01月26日T00:00:00.000000', '2000年01月26日T06:00:00.000000',
       '2000年01月26日T12:00:00.000000', '2000年01月26日T18:00:00.000000',
       '2000年01月27日T00:00:00.000000', '2000年01月27日T06:00:00.000000',
       '2000年01月27日T12:00:00.000000', '2000年01月27日T18:00:00.000000',
       '2000年01月28日T00:00:00.000000', '2000年01月28日T06:00:00.000000',
       '2000年01月28日T12:00:00.000000', '2000年01月28日T18:00:00.000000',
       '2000年01月29日T00:00:00.000000', '2000年01月29日T06:00:00.000000',
       '2000年01月29日T12:00:00.000000', '2000年01月29日T18:00:00.000000',
       '2000年01月30日T00:00:00.000000', '2000年01月30日T06:00:00.000000',
       '2000年01月30日T12:00:00.000000', '2000年01月30日T18:00:00.000000',
       '2000年01月31日T00:00:00.000000', '2000年01月31日T06:00:00.000000',
       '2000年01月31日T12:00:00.000000', '2000年01月31日T18:00:00.000000'],
       dtype='datetime64[us]')
    • foo
      (time)
      int64
      0 1 2 3 4 5 ... 119 120 121 122 123
      array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
       26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
       39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
       91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
       117, 118, 119, 120, 121, 122, 123])

You can also search for multiple months (in this case January through March), using isin:

ds.isel(time=ds.time.dt.month.isin([1, 2, 3]))
<xarray.Dataset> Size: 6kB
Dimensions: (time: 364)
Coordinates:
 * time (time) datetime64[us] 3kB 2000年01月01日 ... 2000年03月31日T18:00:00
Data variables:
 foo (time) int64 3kB 0 1 2 3 4 5 6 7 ... 357 358 359 360 361 362 363
xarray.Dataset
    • time: 364
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年03月31日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年03月31日T06:00:00.000000',
       '2000年03月31日T12:00:00.000000', '2000年03月31日T18:00:00.000000'],
       shape=(364,), dtype='datetime64[us]')
    • foo
      (time)
      int64
      0 1 2 3 4 5 ... 359 360 361 362 363
      array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
       26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
       39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
       91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
       117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
       130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
       143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
       156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
       169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
       182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
       195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
       208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
       221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
       234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
       247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
       260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
       273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,
       286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
       299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311,
       312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
       325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
       338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
       351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363])

Resampling and grouped operations#

See also

For more generic documentation on grouping, see GroupBy: Group and Bin Data.

Datetime components couple particularly well with grouped operations for analyzing features that repeat over time. Here’s how to calculate the mean by time of day:

ds.groupby("time.hour").mean()
<xarray.Dataset> Size: 64B
Dimensions: (hour: 4)
Coordinates:
 * hour (hour) int64 32B 0 6 12 18
Data variables:
 foo (hour) float64 32B 728.0 729.0 730.0 731.0
xarray.Dataset
    • hour: 4
    • hour
      (hour)
      int64
      0 6 12 18
      array([ 0, 6, 12, 18])
    • foo
      (hour)
      float64
      728.0 729.0 730.0 731.0
      array([728., 729., 730., 731.])

For upsampling or downsampling temporal resolutions, xarray offers a Dataset.resample() method building on the core functionality offered by the pandas method of the same name. Resample uses essentially the same api as pandas.DataFrame.resample() in pandas.

For example, we can downsample our dataset from hourly to 6-hourly:

ds.resample(time="6h")
<DatasetResample, grouped over 1 grouper(s), 1460 groups in total:
 '__resample_dim__': TimeResampler('__resample_dim__'), 1460/1460 groups with labels 2000年01月01日, ..., 2000年12月30日T1...>

This will create a specialized DatasetResample or DataArrayResample object which saves information necessary for resampling. All of the reduction methods which work with Dataset or DataArray objects can also be used for resampling:

ds.resample(time="6h").mean()
<xarray.Dataset> Size: 23kB
Dimensions: (time: 1460)
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
Data variables:
 foo (time) float64 12kB 0.0 1.0 2.0 ... 1.457e+03 1.458e+03 1.459e+03
xarray.Dataset
    • time: 1460
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
    • foo
      (time)
      float64
      0.0 1.0 2.0 ... 1.458e+03 1.459e+03
      array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.457e+03, 1.458e+03,
       1.459e+03], shape=(1460,))

You can also supply an arbitrary reduction function to aggregate over each resampling group:

ds.resample(time="6h").reduce(np.mean)
<xarray.Dataset> Size: 23kB
Dimensions: (time: 1460)
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日 ... 2000年12月30日T18:00:00
Data variables:
 foo (time) float64 12kB 0.0 1.0 2.0 ... 1.457e+03 1.458e+03 1.459e+03
xarray.Dataset
    • time: 1460
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T06:00:00.000000',
       '2000年01月01日T12:00:00.000000', ..., '2000年12月30日T06:00:00.000000',
       '2000年12月30日T12:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
    • foo
      (time)
      float64
      0.0 1.0 2.0 ... 1.458e+03 1.459e+03
      array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.457e+03, 1.458e+03,
       1.459e+03], shape=(1460,))

You can also resample on the time dimension while applying reducing along other dimensions at the same time by specifying the dim keyword argument

ds.resample(time="6h").mean(dim=["time", "latitude", "longitude"])

For upsampling, xarray provides six methods: asfreq, ffill, bfill, pad, nearest and interpolate. interpolate extends scipy.interpolate.interp1d() and supports all of its schemes. All of these resampling operations work on both Dataset and DataArray objects with an arbitrary number of dimensions.

In order to limit the scope of the methods ffill, bfill, pad and nearest the tolerance argument can be set in coordinate units. Data that has indices outside of the given tolerance are set to NaN.

ds.resample(time="1h").nearest(tolerance="1h")
<xarray.Dataset> Size: 140kB
Dimensions: (time: 8755)
Coordinates:
 * time (time) datetime64[us] 70kB 2000年01月01日 ... 2000年12月30日T18:00:00
Data variables:
 foo (time) float64 70kB 0.0 0.0 nan nan ... nan nan 1.459e+03 1.459e+03
xarray.Dataset
    • time: 8755
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年12月30日T18:00:00
      array(['2000年01月01日T00:00:00.000000', '2000年01月01日T01:00:00.000000',
       '2000年01月01日T02:00:00.000000', ..., '2000年12月30日T16:00:00.000000',
       '2000年12月30日T17:00:00.000000', '2000年12月30日T18:00:00.000000'],
       shape=(8755,), dtype='datetime64[us]')
    • foo
      (time)
      float64
      0.0 0.0 nan ... 1.459e+03 1.459e+03
      array([ 0., 0., nan, ..., nan, 1459., 1459.], shape=(8755,))

It is often desirable to center the time values after a resampling operation. That can be accomplished by updating the resampled dataset time coordinate values using time offset arithmetic via the pandas.tseries.frequencies.to_offset() function.

resampled_ds = ds.resample(time="6h").mean()
offset = pd.tseries.frequencies.to_offset("6h") / 2
resampled_ds["time"] = resampled_ds.get_index("time") + offset
resampled_ds
<xarray.Dataset> Size: 23kB
Dimensions: (time: 1460)
Coordinates:
 * time (time) datetime64[us] 12kB 2000年01月01日T03:00:00 ... 2000年12月30日T21...
Data variables:
 foo (time) float64 12kB 0.0 1.0 2.0 ... 1.457e+03 1.458e+03 1.459e+03
xarray.Dataset
    • time: 1460
    • time
      (time)
      datetime64[us]
      2000年01月01日T03:00:00 ... 2000-12-...
      array(['2000年01月01日T03:00:00.000000', '2000年01月01日T09:00:00.000000',
       '2000年01月01日T15:00:00.000000', ..., '2000年12月30日T09:00:00.000000',
       '2000年12月30日T15:00:00.000000', '2000年12月30日T21:00:00.000000'],
       shape=(1460,), dtype='datetime64[us]')
    • foo
      (time)
      float64
      0.0 1.0 2.0 ... 1.458e+03 1.459e+03
      array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.457e+03, 1.458e+03,
       1.459e+03], shape=(1460,))

See also

For more examples of using grouped operations on a time dimension, see Toy weather data.

Handling Seasons#

Two extremely common time series operations are to group by seasons, and resample to a seasonal frequency. Xarray has historically supported some simple versions of these computations. For example, .groupby("time.season") (where the seasons are DJF, MAM, JJA, SON) and resampling to a seasonal frequency using Pandas syntax: .resample(time="QS-DEC").

Quite commonly one wants more flexibility in defining seasons. For these use-cases, Xarray provides groupers.SeasonGrouper and groupers.SeasonResampler.

fromxarray.groupersimport SeasonGrouper
ds.groupby(time=SeasonGrouper(["DJF", "MAM", "JJA", "SON"])).mean()
<xarray.Dataset> Size: 64B
Dimensions: (season: 4)
Coordinates:
 * season (season) object 32B 'DJF' 'MAM' 'JJA' 'SON'
Data variables:
 foo (season) float64 32B 546.2 423.5 791.5 1.158e+03
xarray.Dataset
    • season: 4
    • season
      (season)
      object
      'DJF' 'MAM' 'JJA' 'SON'
      array(['DJF', 'MAM', 'JJA', 'SON'], dtype=object)
    • foo
      (season)
      float64
      546.2 423.5 791.5 1.158e+03
      array([ 546.16666667, 423.5 , 791.5 , 1157.5 ])

Note how the seasons are in the specified order, unlike .groupby("time.season") where the seasons are sorted alphabetically.

ds.groupby("time.season").mean()
<xarray.Dataset> Size: 64B
Dimensions: (season: 4)
Coordinates:
 * season (season) object 32B 'DJF' 'JJA' 'MAM' 'SON'
Data variables:
 foo (season) float64 32B 546.2 791.5 423.5 1.158e+03
xarray.Dataset
    • season: 4
    • season
      (season)
      object
      'DJF' 'JJA' 'MAM' 'SON'
      array(['DJF', 'JJA', 'MAM', 'SON'], dtype=object)
    • foo
      (season)
      float64
      546.2 791.5 423.5 1.158e+03
      array([ 546.16666667, 791.5 , 423.5 , 1157.5 ])

SeasonGrouper supports overlapping seasons:

ds.groupby(time=SeasonGrouper(["DJFM", "MAMJ", "JJAS", "SOND"])).mean()
<xarray.Dataset> Size: 64B
Dimensions: (season: 4)
Coordinates:
 * season (season) object 32B 'DJFM' 'MAMJ' 'JJAS' 'SOND'
Data variables:
 foo (season) float64 32B 483.5 483.5 851.5 1.218e+03
xarray.Dataset
    • season: 4
    • season
      (season)
      object
      'DJFM' 'MAMJ' 'JJAS' 'SOND'
      array(['DJFM', 'MAMJ', 'JJAS', 'SOND'], dtype=object)
    • foo
      (season)
      float64
      483.5 483.5 851.5 1.218e+03
      array([ 483.48347107, 483.5 , 851.5 , 1217.5 ])

Skipping months is allowed:

ds.groupby(time=SeasonGrouper(["JJAS"])).mean()
<xarray.Dataset> Size: 16B
Dimensions: (season: 1)
Coordinates:
 * season (season) object 8B 'JJAS'
Data variables:
 foo (season) float64 8B 851.5
xarray.Dataset
    • season: 1
    • season
      (season)
      object
      'JJAS'
      array(['JJAS'], dtype=object)
    • foo
      (season)
      float64
      851.5
      array([851.5])

Use SeasonResampler to specify custom seasons.

fromxarray.groupersimport SeasonResampler
ds.resample(time=SeasonResampler(["DJF", "MAM", "JJA", "SON"])).mean()
<xarray.Dataset> Size: 48B
Dimensions: (time: 3)
Coordinates:
 * time (time) datetime64[us] 24B 2000年03月01日 2000年06月01日 2000年09月01日
Data variables:
 foo (time) float64 24B 423.5 791.5 1.158e+03
xarray.Dataset
    • time: 3
    • time
      (time)
      datetime64[us]
      2000年03月01日 2000年06月01日 2000年09月01日
      array(['2000年03月01日T00:00:00.000000', '2000年06月01日T00:00:00.000000',
       '2000年09月01日T00:00:00.000000'], dtype='datetime64[us]')
    • foo
      (time)
      float64
      423.5 791.5 1.158e+03
      array([ 423.5, 791.5, 1157.5])

SeasonResampler is smart enough to correctly handle years for seasons that span the end of the year (e.g. DJF). By default SeasonResampler will skip any season that is incomplete (e.g. the first DJF season for a time series that starts in Jan). Pass the drop_incomplete=False kwarg to SeasonResampler to disable this behaviour.

fromxarray.groupersimport SeasonResampler
ds.resample(
 time=SeasonResampler(["DJF", "MAM", "JJA", "SON"], drop_incomplete=False)
).mean()
<xarray.Dataset> Size: 80B
Dimensions: (time: 5)
Coordinates:
 * time (time) datetime64[us] 40B 1999年12月01日 2000年03月01日 ... 2000年12月01日
Data variables:
 foo (time) float64 40B 119.5 423.5 791.5 1.158e+03 1.4e+03
xarray.Dataset
    • time: 5
    • time
      (time)
      datetime64[us]
      1999年12月01日 ... 2000年12月01日
      array(['1999年12月01日T00:00:00.000000', '2000年03月01日T00:00:00.000000',
       '2000年06月01日T00:00:00.000000', '2000年09月01日T00:00:00.000000',
       '2000年12月01日T00:00:00.000000'], dtype='datetime64[us]')
    • foo
      (time)
      float64
      119.5 423.5 791.5 1.158e+03 1.4e+03
      array([ 119.5, 423.5, 791.5, 1157.5, 1399.5])

Seasons need not be of the same length:

ds.resample(time=SeasonResampler(["JF", "MAM", "JJAS", "OND"])).mean()
<xarray.Dataset> Size: 64B
Dimensions: (time: 4)
Coordinates:
 * time (time) datetime64[us] 32B 2000年01月01日 2000年03月01日 ... 2000年10月01日
Data variables:
 foo (time) float64 32B 119.5 423.5 851.5 1.278e+03
xarray.Dataset
    • time: 4
    • time
      (time)
      datetime64[us]
      2000年01月01日 ... 2000年10月01日
      array(['2000年01月01日T00:00:00.000000', '2000年03月01日T00:00:00.000000',
       '2000年06月01日T00:00:00.000000', '2000年10月01日T00:00:00.000000'],
       dtype='datetime64[us]')
    • foo
      (time)
      float64
      119.5 423.5 851.5 1.278e+03
      array([ 119.5, 423.5, 851.5, 1277.5])