Skip to content

Instantly share code, notes, and snippets.

@ccarouge
Created May 18, 2020 01:38
Show Gist options
  • Save ccarouge/98e54a56257dd6893ab5cdf234166cb7 to your computer and use it in GitHub Desktop.
Save ccarouge/98e54a56257dd6893ab5cdf234166cb7 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# More about calendars and Xarray\n",
"## Add 29th February\n",
"\n",
"In this notebook, we will see how to change data from a Gregorian calendar to an all leap calendar (all years are leap years) by copying the data from 28th February to 29th February. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# Imports\n",
"import xarray as xr"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since we will work with a non-Gregorian calendar, it is easier not to decode the times when reading the data. So we will have a coordinate with numerical values, a unit and a calendar."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# Data\n",
"ds = xr.open_dataset(\"ts_JRA55_19740227-19740301.nc\",decode_cf=False)\n",
"#ds"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This dataset is relatively small. It is only 3 days of 3-hourly data. We can see it doesn't have a 29th February since it's only 3 days of data.\n",
"But in addition to the time dimension, it also contains a bounds dimension and time_bnds coordinate.\n",
"\n",
"We'll first see how to add the 29th February data and then how to modify the time_bnds array."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First take a copy of the 28th February in separate array to transform it in 29th February. Then we'll add 1 day to the last day of the time series to make some space for the extra day. Then we'll concatenate the 29th February array with the original data. And then change the calendar."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"ts = ds.ts\n",
"#ts.time"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Keep the time attributes for later use:\n",
"new_attrs = {**ts.time.attrs}"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Here we need to assume we know which time values represent the \n",
"# 28th February\n",
"day_length=ts.time.size//3\n",
"ts_29 = ts.isel(time=slice(day_length,2*day_length))\n",
"#ts_29"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, change the time dimension of ts_29 to be 1 more day:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# day_shift is 1 as the unit of the time array is day here.\n",
"# But it could be more if time was in hours for example.\n",
"# See the time attributes for the unit.\n",
"day_shift = ts.time.values[day_length] - ts.time.values[0] \n",
"ts_29.time.values[:] += day_shift\n",
"#ts_29"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create a 1 day \"hole\" in original time coordinate:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"ts.time.values[-day_length:] += day_shift\n",
"#ts"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"ts = xr.concat((ts,ts_29),dim=\"time\")\n",
"#ts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We see the result isn't quite right as the time dimension isn't ordered. Just need a sort:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"ts = ts.sortby(ts.time)\n",
"#ts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we change the calendar to all_leap and decode the times:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"new_attrs[\"calendar\"] = \"all_leap\"\n",
"time = ts.time\n",
"time = time.assign_attrs(**new_attrs)\n",
"ts =ts.assign_coords({\"time\":time})\n",
"#ts.time"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment