Skip to content

Instantly share code, notes, and snippets.

@matt-long
Last active June 7, 2020 16:53
Show Gist options
  • Select an option

  • Save matt-long/357ad9d083fff9ffcce7fbd74cc8dd05 to your computer and use it in GitHub Desktop.

Select an option

Save matt-long/357ad9d083fff9ffcce7fbd74cc8dd05 to your computer and use it in GitHub Desktop.
CESM Timeseries Output: Convert monthly means to annual means
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from glob import glob\n",
"\n",
"import cftime\n",
"import xarray as xr\n",
"import numpy as np\n",
"\n",
"import dask"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<table style=\"border: 2px solid white;\">\n",
"<tr>\n",
"<td style=\"vertical-align: top; border: 0px solid white\">\n",
"<h3 style=\"text-align: left;\">Client</h3>\n",
"<ul style=\"text-align: left; list-style: none; margin: 0; padding: 0;\">\n",
" <li><b>Scheduler: </b>tcp://10.12.205.27:43586</li>\n",
" <li><b>Dashboard: </b><a href='https://jupyterhub.ucar.edu/dav/user/mclong/proxy/8787/status' target='_blank'>https://jupyterhub.ucar.edu/dav/user/mclong/proxy/8787/status</a>\n",
"</ul>\n",
"</td>\n",
"<td style=\"vertical-align: top; border: 0px solid white\">\n",
"<h3 style=\"text-align: left;\">Cluster</h3>\n",
"<ul style=\"text-align: left; list-style:none; margin: 0; padding: 0;\">\n",
" <li><b>Workers: </b>0</li>\n",
" <li><b>Cores: </b>0</li>\n",
" <li><b>Memory: </b>0 B</li>\n",
"</ul>\n",
"</td>\n",
"</tr>\n",
"</table>"
],
"text/plain": [
"<Client: 'tcp://10.12.205.27:43586' processes=0 threads=0, memory=0 B>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from ncar_jobqueue import NCARCluster\n",
"from dask.distributed import Client\n",
"\n",
"try:\n",
" cluster\n",
" client\n",
"except:\n",
" cluster = NCARCluster()\n",
" cluster.scale(32) # appropriate for DAV\n",
" client = Client(cluster) # Connect this local process to remote workers\n",
" \n",
"client"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"dir_out = f'/glade/scratch/{os.environ[\"USER\"]}/data-reduction'\n",
"os.makedirs(dir_out, exist_ok=True)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['/glade/scratch/strandwg/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001/ocn/proc/tseries/month_1/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001.pop.h.NO3.000101-009912.nc',\n",
" '/glade/scratch/strandwg/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001/ocn/proc/tseries/month_1/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001.pop.h.NO3.010001-019912.nc',\n",
" '/glade/scratch/strandwg/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001/ocn/proc/tseries/month_1/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001.pop.h.NO3.020001-029912.nc',\n",
" '/glade/scratch/strandwg/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001/ocn/proc/tseries/month_1/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001.pop.h.NO3.030001-039912.nc',\n",
" '/glade/scratch/strandwg/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001/ocn/proc/tseries/month_1/b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001.pop.h.NO3.040001-050012.nc']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"case = 'b.e21.B1850.f09_g17.cesm2_cmip5_forcing.001'\n",
"dir_proc = 'ocn/proc/tseries/month_1'\n",
"files = sorted(glob(f'/glade/scratch/strandwg/{case}/{dir_proc}/{case}.pop.h.NO3.??????-??????.nc'))\n",
"files"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
"<defs>\n",
"<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
"<title>Show/Hide data repr</title>\n",
"<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
"<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
"<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
"</symbol>\n",
"<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
"<title>Show/Hide attributes</title>\n",
"<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
"<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"</symbol>\n",
"</defs>\n",
"</svg>\n",
"<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
" *\n",
" */\n",
"\n",
":root {\n",
" --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
" --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
" --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
" --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
" --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
" --xr-background-color: var(--jp-layout-color0, white);\n",
" --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
" --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
"}\n",
"\n",
".xr-wrap {\n",
" min-width: 300px;\n",
" max-width: 700px;\n",
"}\n",
"\n",
".xr-header {\n",
" padding-top: 6px;\n",
" padding-bottom: 6px;\n",
" margin-bottom: 4px;\n",
" border-bottom: solid 1px var(--xr-border-color);\n",
"}\n",
"\n",
".xr-header > div,\n",
".xr-header > ul {\n",
" display: inline;\n",
" margin-top: 0;\n",
" margin-bottom: 0;\n",
"}\n",
"\n",
".xr-obj-type,\n",
".xr-array-name {\n",
" margin-left: 2px;\n",
" margin-right: 10px;\n",
"}\n",
"\n",
".xr-obj-type {\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-sections {\n",
" padding-left: 0 !important;\n",
" display: grid;\n",
" grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
"}\n",
"\n",
".xr-section-item {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-section-item input {\n",
" display: none;\n",
"}\n",
"\n",
".xr-section-item input + label {\n",
" color: var(--xr-disabled-color);\n",
"}\n",
"\n",
".xr-section-item input:enabled + label {\n",
" cursor: pointer;\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-section-item input:enabled + label:hover {\n",
" color: var(--xr-font-color0);\n",
"}\n",
"\n",
".xr-section-summary {\n",
" grid-column: 1;\n",
" color: var(--xr-font-color2);\n",
" font-weight: 500;\n",
"}\n",
"\n",
".xr-section-summary > span {\n",
" display: inline-block;\n",
" padding-left: 0.5em;\n",
"}\n",
"\n",
".xr-section-summary-in:disabled + label {\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-section-summary-in + label:before {\n",
" display: inline-block;\n",
" content: '►';\n",
" font-size: 11px;\n",
" width: 15px;\n",
" text-align: center;\n",
"}\n",
"\n",
".xr-section-summary-in:disabled + label:before {\n",
" color: var(--xr-disabled-color);\n",
"}\n",
"\n",
".xr-section-summary-in:checked + label:before {\n",
" content: '▼';\n",
"}\n",
"\n",
".xr-section-summary-in:checked + label > span {\n",
" display: none;\n",
"}\n",
"\n",
".xr-section-summary,\n",
".xr-section-inline-details {\n",
" padding-top: 4px;\n",
" padding-bottom: 4px;\n",
"}\n",
"\n",
".xr-section-inline-details {\n",
" grid-column: 2 / -1;\n",
"}\n",
"\n",
".xr-section-details {\n",
" display: none;\n",
" grid-column: 1 / -1;\n",
" margin-bottom: 5px;\n",
"}\n",
"\n",
".xr-section-summary-in:checked ~ .xr-section-details {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-array-wrap {\n",
" grid-column: 1 / -1;\n",
" display: grid;\n",
" grid-template-columns: 20px auto;\n",
"}\n",
"\n",
".xr-array-wrap > label {\n",
" grid-column: 1;\n",
" vertical-align: top;\n",
"}\n",
"\n",
".xr-preview {\n",
" color: var(--xr-font-color3);\n",
"}\n",
"\n",
".xr-array-preview,\n",
".xr-array-data {\n",
" padding: 0 5px !important;\n",
" grid-column: 2;\n",
"}\n",
"\n",
".xr-array-data,\n",
".xr-array-in:checked ~ .xr-array-preview {\n",
" display: none;\n",
"}\n",
"\n",
".xr-array-in:checked ~ .xr-array-data,\n",
".xr-array-preview {\n",
" display: inline-block;\n",
"}\n",
"\n",
".xr-dim-list {\n",
" display: inline-block !important;\n",
" list-style: none;\n",
" padding: 0 !important;\n",
" margin: 0;\n",
"}\n",
"\n",
".xr-dim-list li {\n",
" display: inline-block;\n",
" padding: 0;\n",
" margin: 0;\n",
"}\n",
"\n",
".xr-dim-list:before {\n",
" content: '(';\n",
"}\n",
"\n",
".xr-dim-list:after {\n",
" content: ')';\n",
"}\n",
"\n",
".xr-dim-list li:not(:last-child):after {\n",
" content: ',';\n",
" padding-right: 5px;\n",
"}\n",
"\n",
".xr-has-index {\n",
" font-weight: bold;\n",
"}\n",
"\n",
".xr-var-list,\n",
".xr-var-item {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-var-item > div,\n",
".xr-var-item label,\n",
".xr-var-item > .xr-var-name span {\n",
" background-color: var(--xr-background-color-row-even);\n",
" margin-bottom: 0;\n",
"}\n",
"\n",
".xr-var-item > .xr-var-name:hover span {\n",
" padding-right: 5px;\n",
"}\n",
"\n",
".xr-var-list > li:nth-child(odd) > div,\n",
".xr-var-list > li:nth-child(odd) > label,\n",
".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
" background-color: var(--xr-background-color-row-odd);\n",
"}\n",
"\n",
".xr-var-name {\n",
" grid-column: 1;\n",
"}\n",
"\n",
".xr-var-dims {\n",
" grid-column: 2;\n",
"}\n",
"\n",
".xr-var-dtype {\n",
" grid-column: 3;\n",
" text-align: right;\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-var-preview {\n",
" grid-column: 4;\n",
"}\n",
"\n",
".xr-var-name,\n",
".xr-var-dims,\n",
".xr-var-dtype,\n",
".xr-preview,\n",
".xr-attrs dt {\n",
" white-space: nowrap;\n",
" overflow: hidden;\n",
" text-overflow: ellipsis;\n",
" padding-right: 10px;\n",
"}\n",
"\n",
".xr-var-name:hover,\n",
".xr-var-dims:hover,\n",
".xr-var-dtype:hover,\n",
".xr-attrs dt:hover {\n",
" overflow: visible;\n",
" width: auto;\n",
" z-index: 1;\n",
"}\n",
"\n",
".xr-var-attrs,\n",
".xr-var-data {\n",
" display: none;\n",
" background-color: var(--xr-background-color) !important;\n",
" padding-bottom: 5px !important;\n",
"}\n",
"\n",
".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
".xr-var-data-in:checked ~ .xr-var-data {\n",
" display: block;\n",
"}\n",
"\n",
".xr-var-data > table {\n",
" float: right;\n",
"}\n",
"\n",
".xr-var-name span,\n",
".xr-var-data,\n",
".xr-attrs {\n",
" padding-left: 25px !important;\n",
"}\n",
"\n",
".xr-attrs,\n",
".xr-var-attrs,\n",
".xr-var-data {\n",
" grid-column: 1 / -1;\n",
"}\n",
"\n",
"dl.xr-attrs {\n",
" padding: 0;\n",
" margin: 0;\n",
" display: grid;\n",
" grid-template-columns: 125px auto;\n",
"}\n",
"\n",
".xr-attrs dt, dd {\n",
" padding: 0;\n",
" margin: 0;\n",
" float: left;\n",
" padding-right: 10px;\n",
" width: auto;\n",
"}\n",
"\n",
".xr-attrs dt {\n",
" font-weight: normal;\n",
" grid-column: 1;\n",
"}\n",
"\n",
".xr-attrs dt:hover span {\n",
" display: inline-block;\n",
" background: var(--xr-background-color);\n",
" padding-right: 10px;\n",
"}\n",
"\n",
".xr-attrs dd {\n",
" grid-column: 2;\n",
" white-space: pre-wrap;\n",
" word-break: break-all;\n",
"}\n",
"\n",
".xr-icon-database,\n",
".xr-icon-file-text2 {\n",
" display: inline-block;\n",
" vertical-align: middle;\n",
" width: 1em;\n",
" height: 1.5em !important;\n",
" stroke-width: 0;\n",
" stroke: currentColor;\n",
" fill: currentColor;\n",
"}\n",
"</style><div class='xr-wrap'><div class='xr-header'><div class='xr-obj-type'>xarray.Dataset</div></div><ul class='xr-sections'><li class='xr-section-item'><input id='section-d55168ad-cd30-4808-b7d2-dbb47fb61f68' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-d55168ad-cd30-4808-b7d2-dbb47fb61f68' class='xr-section-summary' title='Expand/collapse section'>Dimensions:</label><div class='xr-section-inline-details'><ul class='xr-dim-list'><li><span class='xr-has-index'>d2</span>: 2</li><li><span class='xr-has-index'>lat</span>: 2</li><li><span class='xr-has-index'>lon</span>: 2</li><li><span class='xr-has-index'>time</span>: 24</li></ul></div><div class='xr-section-details'></div></li><li class='xr-section-item'><input id='section-88bffb54-026b-4924-8491-5f4fedd94c34' class='xr-section-summary-in' type='checkbox' checked><label for='section-88bffb54-026b-4924-8491-5f4fedd94c34' class='xr-section-summary' >Coordinates: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1</div><input id='attrs-7fbea0c6-9735-4b22-a675-707f5fb5f0d8' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-7fbea0c6-9735-4b22-a675-707f5fb5f0d8' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-2351c6dc-0374-4076-8c49-69191eb4cf95' class='xr-var-data-in' type='checkbox'><label for='data-2351c6dc-0374-4076-8c49-69191eb4cf95' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([0, 1])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lon</span></div><div class='xr-var-dims'>(lon)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1</div><input id='attrs-df2c7a25-82f4-42c6-9097-b587355b6861' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-df2c7a25-82f4-42c6-9097-b587355b6861' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-f0b0b410-8630-40af-b16f-0b5f8b14ba16' class='xr-var-data-in' type='checkbox'><label for='data-f0b0b410-8630-40af-b16f-0b5f8b14ba16' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([0, 1])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>0001-02-01 00:00:00 ... 0003-01-01 00:00:00</div><input id='attrs-e97bf728-8cac-4b81-8285-3561c2bb95af' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-e97bf728-8cac-4b81-8285-3561c2bb95af' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-d42cef9c-1298-4217-9fde-24436a83ece7' class='xr-var-data-in' type='checkbox'><label for='data-d42cef9c-1298-4217-9fde-24436a83ece7' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>bounds :</span></dt><dd>time_bound</dd></dl></div><pre class='xr-var-data'>array([cftime.DatetimeNoLeap(1, 2, 1, 0, 0, 0, 0, 4, 32),\n",
" cftime.DatetimeNoLeap(1, 3, 1, 0, 0, 0, 0, 4, 60),\n",
" cftime.DatetimeNoLeap(1, 4, 1, 0, 0, 0, 0, 0, 91),\n",
" cftime.DatetimeNoLeap(1, 5, 1, 0, 0, 0, 0, 2, 121),\n",
" cftime.DatetimeNoLeap(1, 6, 1, 0, 0, 0, 0, 5, 152),\n",
" cftime.DatetimeNoLeap(1, 7, 1, 0, 0, 0, 0, 0, 182),\n",
" cftime.DatetimeNoLeap(1, 8, 1, 0, 0, 0, 0, 3, 213),\n",
" cftime.DatetimeNoLeap(1, 9, 1, 0, 0, 0, 0, 6, 244),\n",
" cftime.DatetimeNoLeap(1, 10, 1, 0, 0, 0, 0, 1, 274),\n",
" cftime.DatetimeNoLeap(1, 11, 1, 0, 0, 0, 0, 4, 305),\n",
" cftime.DatetimeNoLeap(1, 12, 1, 0, 0, 0, 0, 6, 335),\n",
" cftime.DatetimeNoLeap(2, 1, 1, 0, 0, 0, 0, 2, 1),\n",
" cftime.DatetimeNoLeap(2, 2, 1, 0, 0, 0, 0, 5, 32),\n",
" cftime.DatetimeNoLeap(2, 3, 1, 0, 0, 0, 0, 5, 60),\n",
" cftime.DatetimeNoLeap(2, 4, 1, 0, 0, 0, 0, 1, 91),\n",
" cftime.DatetimeNoLeap(2, 5, 1, 0, 0, 0, 0, 3, 121),\n",
" cftime.DatetimeNoLeap(2, 6, 1, 0, 0, 0, 0, 6, 152),\n",
" cftime.DatetimeNoLeap(2, 7, 1, 0, 0, 0, 0, 1, 182),\n",
" cftime.DatetimeNoLeap(2, 8, 1, 0, 0, 0, 0, 4, 213),\n",
" cftime.DatetimeNoLeap(2, 9, 1, 0, 0, 0, 0, 0, 244),\n",
" cftime.DatetimeNoLeap(2, 10, 1, 0, 0, 0, 0, 2, 274),\n",
" cftime.DatetimeNoLeap(2, 11, 1, 0, 0, 0, 0, 5, 305),\n",
" cftime.DatetimeNoLeap(2, 12, 1, 0, 0, 0, 0, 0, 335),\n",
" cftime.DatetimeNoLeap(3, 1, 1, 0, 0, 0, 0, 3, 1)], dtype=object)</pre></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>d2</span></div><div class='xr-var-dims'>(d2)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1</div><input id='attrs-34a55656-e7d9-4449-9868-c5f2ee4d3452' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-34a55656-e7d9-4449-9868-c5f2ee4d3452' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-43f4d69d-9fbe-4568-bb24-3d2e5f110240' class='xr-var-data-in' type='checkbox'><label for='data-43f4d69d-9fbe-4568-bb24-3d2e5f110240' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([0, 1])</pre></li></ul></div></li><li class='xr-section-item'><input id='section-2aa78c79-9ac9-4203-a0e5-9d0af67ab0a1' class='xr-section-summary-in' type='checkbox' checked><label for='section-2aa78c79-9ac9-4203-a0e5-9d0af67ab0a1' class='xr-section-summary' >Data variables: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>time_bound</span></div><div class='xr-var-dims'>(time, d2)</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-63188a30-6da5-4b74-b633-8dea96f350fc' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-63188a30-6da5-4b74-b633-8dea96f350fc' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-80f79f5d-ba2f-4b87-89fa-07dd9d0d10cb' class='xr-var-data-in' type='checkbox'><label for='data-80f79f5d-ba2f-4b87-89fa-07dd9d0d10cb' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([[cftime.DatetimeNoLeap(1, 1, 1, 0, 0, 0, 0, 1, 1),\n",
" cftime.DatetimeNoLeap(1, 2, 1, 0, 0, 0, 0, 4, 32)],\n",
" [cftime.DatetimeNoLeap(1, 2, 1, 0, 0, 0, 0, 4, 32),\n",
" cftime.DatetimeNoLeap(1, 3, 1, 0, 0, 0, 0, 4, 60)],\n",
" [cftime.DatetimeNoLeap(1, 3, 1, 0, 0, 0, 0, 4, 60),\n",
" cftime.DatetimeNoLeap(1, 4, 1, 0, 0, 0, 0, 0, 91)],\n",
" [cftime.DatetimeNoLeap(1, 4, 1, 0, 0, 0, 0, 0, 91),\n",
" cftime.DatetimeNoLeap(1, 5, 1, 0, 0, 0, 0, 2, 121)],\n",
" [cftime.DatetimeNoLeap(1, 5, 1, 0, 0, 0, 0, 2, 121),\n",
" cftime.DatetimeNoLeap(1, 6, 1, 0, 0, 0, 0, 5, 152)],\n",
" [cftime.DatetimeNoLeap(1, 6, 1, 0, 0, 0, 0, 5, 152),\n",
" cftime.DatetimeNoLeap(1, 7, 1, 0, 0, 0, 0, 0, 182)],\n",
" [cftime.DatetimeNoLeap(1, 7, 1, 0, 0, 0, 0, 0, 182),\n",
" cftime.DatetimeNoLeap(1, 8, 1, 0, 0, 0, 0, 3, 213)],\n",
" [cftime.DatetimeNoLeap(1, 8, 1, 0, 0, 0, 0, 3, 213),\n",
" cftime.DatetimeNoLeap(1, 9, 1, 0, 0, 0, 0, 6, 244)],\n",
" [cftime.DatetimeNoLeap(1, 9, 1, 0, 0, 0, 0, 6, 244),\n",
" cftime.DatetimeNoLeap(1, 10, 1, 0, 0, 0, 0, 1, 274)],\n",
" [cftime.DatetimeNoLeap(1, 10, 1, 0, 0, 0, 0, 1, 274),\n",
" cftime.DatetimeNoLeap(1, 11, 1, 0, 0, 0, 0, 4, 305)],\n",
" [cftime.DatetimeNoLeap(1, 11, 1, 0, 0, 0, 0, 4, 305),\n",
" cftime.DatetimeNoLeap(1, 12, 1, 0, 0, 0, 0, 6, 335)],\n",
" [cftime.DatetimeNoLeap(1, 12, 1, 0, 0, 0, 0, 6, 335),\n",
" cftime.DatetimeNoLeap(2, 1, 1, 0, 0, 0, 0, 2, 1)],\n",
" [cftime.DatetimeNoLeap(2, 1, 1, 0, 0, 0, 0, 2, 1),\n",
" cftime.DatetimeNoLeap(2, 2, 1, 0, 0, 0, 0, 5, 32)],\n",
" [cftime.DatetimeNoLeap(2, 2, 1, 0, 0, 0, 0, 5, 32),\n",
" cftime.DatetimeNoLeap(2, 3, 1, 0, 0, 0, 0, 5, 60)],\n",
" [cftime.DatetimeNoLeap(2, 3, 1, 0, 0, 0, 0, 5, 60),\n",
" cftime.DatetimeNoLeap(2, 4, 1, 0, 0, 0, 0, 1, 91)],\n",
" [cftime.DatetimeNoLeap(2, 4, 1, 0, 0, 0, 0, 1, 91),\n",
" cftime.DatetimeNoLeap(2, 5, 1, 0, 0, 0, 0, 3, 121)],\n",
" [cftime.DatetimeNoLeap(2, 5, 1, 0, 0, 0, 0, 3, 121),\n",
" cftime.DatetimeNoLeap(2, 6, 1, 0, 0, 0, 0, 6, 152)],\n",
" [cftime.DatetimeNoLeap(2, 6, 1, 0, 0, 0, 0, 6, 152),\n",
" cftime.DatetimeNoLeap(2, 7, 1, 0, 0, 0, 0, 1, 182)],\n",
" [cftime.DatetimeNoLeap(2, 7, 1, 0, 0, 0, 0, 1, 182),\n",
" cftime.DatetimeNoLeap(2, 8, 1, 0, 0, 0, 0, 4, 213)],\n",
" [cftime.DatetimeNoLeap(2, 8, 1, 0, 0, 0, 0, 4, 213),\n",
" cftime.DatetimeNoLeap(2, 9, 1, 0, 0, 0, 0, 0, 244)],\n",
" [cftime.DatetimeNoLeap(2, 9, 1, 0, 0, 0, 0, 0, 244),\n",
" cftime.DatetimeNoLeap(2, 10, 1, 0, 0, 0, 0, 2, 274)],\n",
" [cftime.DatetimeNoLeap(2, 10, 1, 0, 0, 0, 0, 2, 274),\n",
" cftime.DatetimeNoLeap(2, 11, 1, 0, 0, 0, 0, 5, 305)],\n",
" [cftime.DatetimeNoLeap(2, 11, 1, 0, 0, 0, 0, 5, 305),\n",
" cftime.DatetimeNoLeap(2, 12, 1, 0, 0, 0, 0, 0, 335)],\n",
" [cftime.DatetimeNoLeap(2, 12, 1, 0, 0, 0, 0, 0, 335),\n",
" cftime.DatetimeNoLeap(3, 1, 1, 0, 0, 0, 0, 3, 1)]], dtype=object)</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>variable_1</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-768236f1-968a-4ef2-aa44-2c0534550a03' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-768236f1-968a-4ef2-aa44-2c0534550a03' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-ce9b3b2a-7b0b-4bfd-9b5f-e055e9da6032' class='xr-var-data-in' type='checkbox'><label for='data-ce9b3b2a-7b0b-4bfd-9b5f-e055e9da6032' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>description :</span></dt><dd>All zeroes for year 1, all ones for year 2</dd></dl></div><pre class='xr-var-data'>array([[[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]]], dtype=float32)</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>variable_2</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-de2982df-a087-4326-bf8d-aff4e9475e25' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-de2982df-a087-4326-bf8d-aff4e9475e25' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-61602927-1681-44b6-a8b0-7145f95a73e0' class='xr-var-data-in' type='checkbox'><label for='data-61602927-1681-44b6-a8b0-7145f95a73e0' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>description :</span></dt><dd>All ones for year 1, all zeroes for year 2</dd></dl></div><pre class='xr-var-data'>array([[[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]]], dtype=float32)</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>non_time_variable_1</span></div><div class='xr-var-dims'>(lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-af718a30-e89c-4f0d-9c74-8fb24691c1db' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-af718a30-e89c-4f0d-9c74-8fb24691c1db' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-e9a6c255-fda4-4003-87b1-b9981d2a2b4b' class='xr-var-data-in' type='checkbox'><label for='data-e9a6c255-fda4-4003-87b1-b9981d2a2b4b' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([[1., 1.],\n",
" [1., 1.]])</pre></li></ul></div></li><li class='xr-section-item'><input id='section-111da4bb-f4b8-42f3-995c-9e95afcfd357' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-111da4bb-f4b8-42f3-995c-9e95afcfd357' class='xr-section-summary' title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
],
"text/plain": [
"<xarray.Dataset>\n",
"Dimensions: (d2: 2, lat: 2, lon: 2, time: 24)\n",
"Coordinates:\n",
" * lat (lat) int64 0 1\n",
" * lon (lon) int64 0 1\n",
" * time (time) object 0001-02-01 00:00:00 ... 0003-01-01 00:00:00\n",
" * d2 (d2) int64 0 1\n",
"Data variables:\n",
" time_bound (time, d2) object ...\n",
" variable_1 (time, lat, lon) float32 ...\n",
" variable_2 (time, lat, lon) float32 ...\n",
" non_time_variable_1 (lat, lon) float64 ..."
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def dset():\n",
" \"\"\"Generate a simple test dataset\"\"\"\n",
" \n",
" start_date = np.array([0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], dtype=np.float64)\n",
" start_date = np.append(start_date, start_date + 365)\n",
" end_date = np.array([31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365], dtype=np.float64)\n",
" end_date = np.append(end_date, end_date + 365)\n",
"\n",
" ds = xr.Dataset(coords={'time': 24, 'lat': 2, 'lon': 2, 'd2': 2})\n",
" ds['time'] = xr.DataArray(end_date, dims='time')\n",
" ds['lat'] = xr.DataArray([0, 1], dims='lat')\n",
" ds['lon'] = xr.DataArray([0, 1], dims='lon')\n",
" ds['d2'] = xr.DataArray([0, 1], dims='d2')\n",
" ds['time_bound'] = xr.DataArray(\n",
" np.array([start_date, end_date]).transpose(), dims=['time', 'd2']\n",
" )\n",
" ds['variable_1'] = xr.DataArray(\n",
" np.append(\n",
" np.zeros([12, 2, 2], dtype='float32'), np.ones([12, 2, 2], dtype='float32'), axis=0\n",
" ),\n",
" dims=['time', 'lat', 'lon'],\n",
" )\n",
" ds.variable_1.attrs['description'] = 'All zeroes for year 1, all ones for year 2'\n",
" \n",
" ds['variable_2'] = xr.DataArray(\n",
" np.append(\n",
" np.ones([12, 2, 2], dtype='float32'), np.zeros([12, 2, 2], dtype='float32'), axis=0\n",
" ),\n",
" dims=['time', 'lat', 'lon'],\n",
" )\n",
" ds.variable_2.attrs['description'] = 'All ones for year 1, all zeroes for year 2'\n",
" \n",
" ds['non_time_variable_1'] = xr.DataArray(np.ones((2, 2)), dims=['lat', 'lon'])\n",
" \n",
" ds.time.attrs['units'] = 'days since 0001-01-01 00:00:00'\n",
" ds.time.attrs['calendar'] = 'noleap'\n",
" ds.time.attrs['bounds'] = 'time_bound'\n",
"\n",
" return xr.decode_cf(ds.copy(True))\n",
"\n",
"ds_test = dset()\n",
"ds_test"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
"<defs>\n",
"<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
"<title>Show/Hide data repr</title>\n",
"<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
"<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
"<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
"</symbol>\n",
"<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
"<title>Show/Hide attributes</title>\n",
"<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
"<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
"</symbol>\n",
"</defs>\n",
"</svg>\n",
"<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
" *\n",
" */\n",
"\n",
":root {\n",
" --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
" --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
" --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
" --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
" --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
" --xr-background-color: var(--jp-layout-color0, white);\n",
" --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
" --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
"}\n",
"\n",
".xr-wrap {\n",
" min-width: 300px;\n",
" max-width: 700px;\n",
"}\n",
"\n",
".xr-header {\n",
" padding-top: 6px;\n",
" padding-bottom: 6px;\n",
" margin-bottom: 4px;\n",
" border-bottom: solid 1px var(--xr-border-color);\n",
"}\n",
"\n",
".xr-header > div,\n",
".xr-header > ul {\n",
" display: inline;\n",
" margin-top: 0;\n",
" margin-bottom: 0;\n",
"}\n",
"\n",
".xr-obj-type,\n",
".xr-array-name {\n",
" margin-left: 2px;\n",
" margin-right: 10px;\n",
"}\n",
"\n",
".xr-obj-type {\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-sections {\n",
" padding-left: 0 !important;\n",
" display: grid;\n",
" grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
"}\n",
"\n",
".xr-section-item {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-section-item input {\n",
" display: none;\n",
"}\n",
"\n",
".xr-section-item input + label {\n",
" color: var(--xr-disabled-color);\n",
"}\n",
"\n",
".xr-section-item input:enabled + label {\n",
" cursor: pointer;\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-section-item input:enabled + label:hover {\n",
" color: var(--xr-font-color0);\n",
"}\n",
"\n",
".xr-section-summary {\n",
" grid-column: 1;\n",
" color: var(--xr-font-color2);\n",
" font-weight: 500;\n",
"}\n",
"\n",
".xr-section-summary > span {\n",
" display: inline-block;\n",
" padding-left: 0.5em;\n",
"}\n",
"\n",
".xr-section-summary-in:disabled + label {\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-section-summary-in + label:before {\n",
" display: inline-block;\n",
" content: '►';\n",
" font-size: 11px;\n",
" width: 15px;\n",
" text-align: center;\n",
"}\n",
"\n",
".xr-section-summary-in:disabled + label:before {\n",
" color: var(--xr-disabled-color);\n",
"}\n",
"\n",
".xr-section-summary-in:checked + label:before {\n",
" content: '▼';\n",
"}\n",
"\n",
".xr-section-summary-in:checked + label > span {\n",
" display: none;\n",
"}\n",
"\n",
".xr-section-summary,\n",
".xr-section-inline-details {\n",
" padding-top: 4px;\n",
" padding-bottom: 4px;\n",
"}\n",
"\n",
".xr-section-inline-details {\n",
" grid-column: 2 / -1;\n",
"}\n",
"\n",
".xr-section-details {\n",
" display: none;\n",
" grid-column: 1 / -1;\n",
" margin-bottom: 5px;\n",
"}\n",
"\n",
".xr-section-summary-in:checked ~ .xr-section-details {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-array-wrap {\n",
" grid-column: 1 / -1;\n",
" display: grid;\n",
" grid-template-columns: 20px auto;\n",
"}\n",
"\n",
".xr-array-wrap > label {\n",
" grid-column: 1;\n",
" vertical-align: top;\n",
"}\n",
"\n",
".xr-preview {\n",
" color: var(--xr-font-color3);\n",
"}\n",
"\n",
".xr-array-preview,\n",
".xr-array-data {\n",
" padding: 0 5px !important;\n",
" grid-column: 2;\n",
"}\n",
"\n",
".xr-array-data,\n",
".xr-array-in:checked ~ .xr-array-preview {\n",
" display: none;\n",
"}\n",
"\n",
".xr-array-in:checked ~ .xr-array-data,\n",
".xr-array-preview {\n",
" display: inline-block;\n",
"}\n",
"\n",
".xr-dim-list {\n",
" display: inline-block !important;\n",
" list-style: none;\n",
" padding: 0 !important;\n",
" margin: 0;\n",
"}\n",
"\n",
".xr-dim-list li {\n",
" display: inline-block;\n",
" padding: 0;\n",
" margin: 0;\n",
"}\n",
"\n",
".xr-dim-list:before {\n",
" content: '(';\n",
"}\n",
"\n",
".xr-dim-list:after {\n",
" content: ')';\n",
"}\n",
"\n",
".xr-dim-list li:not(:last-child):after {\n",
" content: ',';\n",
" padding-right: 5px;\n",
"}\n",
"\n",
".xr-has-index {\n",
" font-weight: bold;\n",
"}\n",
"\n",
".xr-var-list,\n",
".xr-var-item {\n",
" display: contents;\n",
"}\n",
"\n",
".xr-var-item > div,\n",
".xr-var-item label,\n",
".xr-var-item > .xr-var-name span {\n",
" background-color: var(--xr-background-color-row-even);\n",
" margin-bottom: 0;\n",
"}\n",
"\n",
".xr-var-item > .xr-var-name:hover span {\n",
" padding-right: 5px;\n",
"}\n",
"\n",
".xr-var-list > li:nth-child(odd) > div,\n",
".xr-var-list > li:nth-child(odd) > label,\n",
".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
" background-color: var(--xr-background-color-row-odd);\n",
"}\n",
"\n",
".xr-var-name {\n",
" grid-column: 1;\n",
"}\n",
"\n",
".xr-var-dims {\n",
" grid-column: 2;\n",
"}\n",
"\n",
".xr-var-dtype {\n",
" grid-column: 3;\n",
" text-align: right;\n",
" color: var(--xr-font-color2);\n",
"}\n",
"\n",
".xr-var-preview {\n",
" grid-column: 4;\n",
"}\n",
"\n",
".xr-var-name,\n",
".xr-var-dims,\n",
".xr-var-dtype,\n",
".xr-preview,\n",
".xr-attrs dt {\n",
" white-space: nowrap;\n",
" overflow: hidden;\n",
" text-overflow: ellipsis;\n",
" padding-right: 10px;\n",
"}\n",
"\n",
".xr-var-name:hover,\n",
".xr-var-dims:hover,\n",
".xr-var-dtype:hover,\n",
".xr-attrs dt:hover {\n",
" overflow: visible;\n",
" width: auto;\n",
" z-index: 1;\n",
"}\n",
"\n",
".xr-var-attrs,\n",
".xr-var-data {\n",
" display: none;\n",
" background-color: var(--xr-background-color) !important;\n",
" padding-bottom: 5px !important;\n",
"}\n",
"\n",
".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
".xr-var-data-in:checked ~ .xr-var-data {\n",
" display: block;\n",
"}\n",
"\n",
".xr-var-data > table {\n",
" float: right;\n",
"}\n",
"\n",
".xr-var-name span,\n",
".xr-var-data,\n",
".xr-attrs {\n",
" padding-left: 25px !important;\n",
"}\n",
"\n",
".xr-attrs,\n",
".xr-var-attrs,\n",
".xr-var-data {\n",
" grid-column: 1 / -1;\n",
"}\n",
"\n",
"dl.xr-attrs {\n",
" padding: 0;\n",
" margin: 0;\n",
" display: grid;\n",
" grid-template-columns: 125px auto;\n",
"}\n",
"\n",
".xr-attrs dt, dd {\n",
" padding: 0;\n",
" margin: 0;\n",
" float: left;\n",
" padding-right: 10px;\n",
" width: auto;\n",
"}\n",
"\n",
".xr-attrs dt {\n",
" font-weight: normal;\n",
" grid-column: 1;\n",
"}\n",
"\n",
".xr-attrs dt:hover span {\n",
" display: inline-block;\n",
" background: var(--xr-background-color);\n",
" padding-right: 10px;\n",
"}\n",
"\n",
".xr-attrs dd {\n",
" grid-column: 2;\n",
" white-space: pre-wrap;\n",
" word-break: break-all;\n",
"}\n",
"\n",
".xr-icon-database,\n",
".xr-icon-file-text2 {\n",
" display: inline-block;\n",
" vertical-align: middle;\n",
" width: 1em;\n",
" height: 1.5em !important;\n",
" stroke-width: 0;\n",
" stroke: currentColor;\n",
" fill: currentColor;\n",
"}\n",
"</style><div class='xr-wrap'><div class='xr-header'><div class='xr-obj-type'>xarray.Dataset</div></div><ul class='xr-sections'><li class='xr-section-item'><input id='section-500afdae-b4bf-45f2-8519-cd2494d3c558' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-500afdae-b4bf-45f2-8519-cd2494d3c558' class='xr-section-summary' title='Expand/collapse section'>Dimensions:</label><div class='xr-section-inline-details'><ul class='xr-dim-list'><li><span>d2</span>: 2</li><li><span class='xr-has-index'>lat</span>: 2</li><li><span class='xr-has-index'>lon</span>: 2</li><li><span class='xr-has-index'>time</span>: 2</li></ul></div><div class='xr-section-details'></div></li><li class='xr-section-item'><input id='section-252a2809-bc66-4ad2-94fd-5756d6880232' class='xr-section-summary-in' type='checkbox' checked><label for='section-252a2809-bc66-4ad2-94fd-5756d6880232' class='xr-section-summary' >Coordinates: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>365.0 730.0</div><input id='attrs-d375dd86-4164-4b79-9290-b29a252215ff' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-d375dd86-4164-4b79-9290-b29a252215ff' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-0bc4e5bf-b0ec-4350-9291-db81d77d0772' class='xr-var-data-in' type='checkbox'><label for='data-0bc4e5bf-b0ec-4350-9291-db81d77d0772' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>units :</span></dt><dd>days since 0001-01-01 00:00:00</dd><dt><span>calendar :</span></dt><dd>noleap</dd></dl></div><pre class='xr-var-data'>array([365., 730.])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1</div><input id='attrs-52b9e792-8368-4ed6-a10a-3b1efdaba491' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-52b9e792-8368-4ed6-a10a-3b1efdaba491' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-69ab3d7c-1ae9-49cc-92c4-2372827bc545' class='xr-var-data-in' type='checkbox'><label for='data-69ab3d7c-1ae9-49cc-92c4-2372827bc545' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([0, 1])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lon</span></div><div class='xr-var-dims'>(lon)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1</div><input id='attrs-9c052c5a-866e-4eac-a49a-e6165c089407' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-9c052c5a-866e-4eac-a49a-e6165c089407' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-da95598c-8475-4613-95b4-54a7258d447f' class='xr-var-data-in' type='checkbox'><label for='data-da95598c-8475-4613-95b4-54a7258d447f' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([0, 1])</pre></li></ul></div></li><li class='xr-section-item'><input id='section-007847b6-67f8-484a-b581-77f1037c16fe' class='xr-section-summary-in' type='checkbox' checked><label for='section-007847b6-67f8-484a-b581-77f1037c16fe' class='xr-section-summary' >Data variables: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>variable_1</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0</div><input id='attrs-99294f48-3ae3-4da1-a898-40c83b993a61' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-99294f48-3ae3-4da1-a898-40c83b993a61' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-b4de06a1-3971-4f3b-a0b4-82cbc4e0c99b' class='xr-var-data-in' type='checkbox'><label for='data-b4de06a1-3971-4f3b-a0b4-82cbc4e0c99b' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>description :</span></dt><dd>All zeroes for year 1, all ones for year 2</dd></dl></div><pre class='xr-var-data'>array([[[0., 0.],\n",
" [0., 0.]],\n",
"\n",
" [[1., 1.],\n",
" [1., 1.]]])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>variable_2</span></div><div class='xr-var-dims'>(time, lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0</div><input id='attrs-b19034bb-a30b-46f4-a784-98a9a42e1f98' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-b19034bb-a30b-46f4-a784-98a9a42e1f98' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-2069f748-c762-4739-9259-79a565a4abe5' class='xr-var-data-in' type='checkbox'><label for='data-2069f748-c762-4739-9259-79a565a4abe5' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>description :</span></dt><dd>All ones for year 1, all zeroes for year 2</dd></dl></div><pre class='xr-var-data'>array([[[1., 1.],\n",
" [1., 1.]],\n",
"\n",
" [[0., 0.],\n",
" [0., 0.]]])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>non_time_variable_1</span></div><div class='xr-var-dims'>(lat, lon)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-ba305a27-90cb-4b90-ab1a-d7b64c8ea734' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-ba305a27-90cb-4b90-ab1a-d7b64c8ea734' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-2e98e6cc-6bbf-4f76-9610-2bd339579a62' class='xr-var-data-in' type='checkbox'><label for='data-2e98e6cc-6bbf-4f76-9610-2bd339579a62' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([[1., 1.],\n",
" [1., 1.]])</pre></li><li class='xr-var-item'><div class='xr-var-name'><span>time_bound</span></div><div class='xr-var-dims'>(time, d2)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.0 365.0 365.0 730.0</div><input id='attrs-6f01f6e3-73b9-48d3-8b19-314c55756555' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-6f01f6e3-73b9-48d3-8b19-314c55756555' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-ab46f917-8923-45f5-8782-29b8996739c0' class='xr-var-data-in' type='checkbox'><label for='data-ab46f917-8923-45f5-8782-29b8996739c0' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><pre class='xr-var-data'>array([[ 0., 365.],\n",
" [365., 730.]])</pre></li></ul></div></li><li class='xr-section-item'><input id='section-4febe511-b861-4a92-8685-c966c0dfebf2' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-4febe511-b861-4a92-8685-c966c0dfebf2' class='xr-section-summary' title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
],
"text/plain": [
"<xarray.Dataset>\n",
"Dimensions: (d2: 2, lat: 2, lon: 2, time: 2)\n",
"Coordinates:\n",
" * time (time) float64 365.0 730.0\n",
" * lat (lat) int64 0 1\n",
" * lon (lon) int64 0 1\n",
"Dimensions without coordinates: d2\n",
"Data variables:\n",
" variable_1 (time, lat, lon) float64 0.0 0.0 0.0 ... 1.0 1.0 1.0\n",
" variable_2 (time, lat, lon) float64 1.0 1.0 1.0 ... 0.0 0.0 0.0\n",
" non_time_variable_1 (lat, lon) float64 ...\n",
" time_bound (time, d2) float64 0.0 365.0 365.0 730.0"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def compute_ann_means(dset):\n",
" \"\"\"compute annual means\"\"\"\n",
" \n",
" time_coord_name = 'time'\n",
" time_dot_year = 'time.year'\n",
"\n",
" time_bnds_varname = dset.time.bounds\n",
" tb_dim = dset[time_bnds_varname].dims[-1]\n",
" time_units = dset.time.encoding['units']\n",
" time_calendar = dset.time.encoding['calendar']\n",
"\n",
" # compute time bounds array\n",
" time_bound_data = cftime.date2num(\n",
" dset[time_bnds_varname].data, \n",
" units=time_units, \n",
" calendar=time_calendar) \n",
"\n",
" # center time\n",
" time_centered = cftime.num2date(\n",
" time_bound_data.mean(axis=1),\n",
" units=time_units, \n",
" calendar=time_calendar\n",
" ) \n",
" time_attrs = dset.time.attrs\n",
" time_encoding = dset.time.encoding\n",
"\n",
" dset['time'] = xr.DataArray(\n",
" time_centered,\n",
" dims=('time')\n",
" )\n",
" dset.time.attrs = time_attrs\n",
" dset.time.encoding = time_encoding\n",
" \n",
" # make time bound DataArray\n",
" time_bound = xr.DataArray(\n",
" time_bound_data,\n",
" dims=('time', tb_dim),\n",
" coords={'time': dset['time']}\n",
" ) \n",
" \n",
" time_wgt = xr.DataArray(\n",
" np.diff(time_bound, axis=1).squeeze(),\n",
" dims=('time'),\n",
" coords={'time': dset.time},\n",
" ) \n",
" \n",
" time_wgt_grouped = time_wgt.groupby(time_dot_year)\n",
" wgts = time_wgt_grouped / time_wgt_grouped.sum(dim=xr.ALL_DIMS)\n",
"\n",
" nyr = len(time_wgt_grouped.groups)\n",
" wgts = wgts.squeeze()\n",
"\n",
" # ensure that weights sum to 1\n",
" np.testing.assert_almost_equal(\n",
" wgts.groupby(time_dot_year).sum(dim=xr.ALL_DIMS), \n",
" np.ones(nyr)\n",
" )\n",
"\n",
" wgts = wgts.rename('weights')\n",
"\n",
" \n",
" # set non-time related vars to coords to avoid xarray adding a time-dim\n",
" nontime_vars = list(set([v for v in dset.variables if 'time' not in dset[v].dims]) - set(dset.coords))\n",
" dsop = dset.drop(nontime_vars+[time_bnds_varname])\n",
"\n",
" def weighted_mean_arr(darr, wgts=None):\n",
" # if NaN are present, we need to use individual weights\n",
" cond = darr.isnull()\n",
" ones = xr.where(cond, 0.0, 1.0)\n",
" mask = (\n",
" darr.resample({time_coord_name: 'A'}).mean(dim=time_coord_name).notnull()\n",
" )\n",
" da_sum = (\n",
" (darr * wgts).resample({time_coord_name: 'A'}).sum(dim=time_coord_name)\n",
" )\n",
" ones_out = (\n",
" (ones * wgts).resample({time_coord_name: 'A'}).sum(dim=time_coord_name)\n",
" )\n",
" ones_out = ones_out.where(ones_out > 0.0)\n",
" da_weighted_mean = da_sum / ones_out\n",
" return da_weighted_mean.where(mask)\n",
"\n",
" # compute\n",
" computed_dset = dsop.apply(weighted_mean_arr, wgts=wgts)\n",
"\n",
" # put variables back\n",
" computed_dset = xr.merge((computed_dset, dset[nontime_vars]))\n",
"\n",
" # set time-bounds\n",
" tb_out_lo = (\n",
" time_bound[:, 0]\n",
" .groupby(time_dot_year)\n",
" .min(dim=time_coord_name)\n",
" .rename({'year': time_coord_name})\n",
" )\n",
" tb_out_hi = (\n",
" time_bound[:, 1]\n",
" .groupby(time_dot_year)\n",
" .max(dim=time_coord_name)\n",
" .rename({'year': time_coord_name})\n",
" )\n",
" \n",
" tb_data_new_shape = (dset[time_coord_name].data.shape[0], 2)\n",
" tb_data = xr.concat((tb_out_lo, tb_out_hi), dim=tb_dim).transpose(time_coord_name, tb_dim)\n",
" tb_data = tb_data.assign_coords(time=computed_dset.time)\n",
" \n",
" computed_dset[time_bnds_varname] = tb_data.compute()\n",
" \n",
" # copy back encoding and attrs\n",
" preserve_encodings = ['dtype', '_FillValue', 'units', 'calendar']\n",
" for v in computed_dset.variables:\n",
" encoding = {\n",
" key: val for key, val in dset[v].encoding.items() \n",
" if key in preserve_encodings\n",
" }\n",
" attrs = dset[v].attrs\n",
" if '_FillValue' not in encoding:\n",
" encoding['_FillValue'] = None\n",
" \n",
" computed_dset[v].encoding = encoding\n",
" computed_dset[v].attrs = attrs\n",
" \n",
" return computed_dset\n",
"\n",
"\n",
"def prepare_to_serialize(dset):\n",
" \"\"\"Make some modification before writing to file\"\"\"\n",
" time_bnds_varname = dset.time.bounds\n",
" encoding = dset.time.encoding\n",
" time_units = encoding.pop('units')\n",
" time_calendar = encoding.pop('calendar')\n",
" encoding['_FillValue'] = None\n",
" \n",
" dset['time'] = xr.DataArray(\n",
" dset[time_bnds_varname].data[:, 1],\n",
" dims=('time'),\n",
" attrs={'units': time_units, 'calendar': time_calendar})\n",
" dset.time.encoding = encoding\n",
" return dset\n",
"\n",
"\n",
"ds_test_ann = compute_ann_means(ds_test)\n",
"\n",
"assert (ds_test_ann.variable_1.isel(time=0).values == 0.).all()\n",
"assert (ds_test_ann.variable_1.isel(time=1).values == 1.).all()\n",
"\n",
"assert (ds_test_ann.variable_2.isel(time=0).values == 1.).all()\n",
"assert (ds_test_ann.variable_2.isel(time=1).values == 0.).all()\n",
"\n",
"ds = prepare_to_serialize(ds_test_ann)\n",
"ds"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"@dask.delayed\n",
"def compress(ncfile):\n",
" \"\"\"\n",
" Call ncks\n",
" \n",
" Parameter\n",
" ---------\n",
" files : str\n",
" The file to compress\n",
" \"\"\"\n",
" from subprocess import PIPE, Popen\n",
" \n",
" ncks_cmd = ' '.join(['ncks', '-O', '-4', '-L', '1', ncfile, ncfile])\n",
" cmd = ' && '.join(['module load nco', ncks_cmd])\n",
" \n",
" p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)\n",
" \n",
" stdout, stderr = p.communicate()\n",
" if p.returncode != 0:\n",
" print(stdout.decode('UTF-8'))\n",
" print(stderr.decode('UTF-8'))\n",
" raise "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"open_kwargs = dict(\n",
" decode_coords=False,\n",
" decode_times=True,\n",
" use_cftime=True,\n",
" chunks=dict(time=12),\n",
")\n",
"\n",
"def annualize(file_in, file_out): \n",
" with xr.open_dataset(file_in, **open_kwargs) as ds:\n",
" ds_ann = compute_ann_means(ds)\n",
" prepare_to_serialize(ds_ann).to_netcdf(file_out)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 42.6 s, sys: 2.09 s, total: 44.6 s\n",
"Wall time: 2min 27s\n"
]
}
],
"source": [
"%%time\n",
"delayed = []\n",
"for file_in in files:\n",
" # name output file\n",
" file_in_basename = os.path.basename(file_in)\n",
" file_out = f'{dir_out}/{file_in_basename}'\n",
"\n",
" # compute annual mean\n",
" annualize(file_in, file_out)\n",
" \n",
" # apply compression\n",
" delayed.append(compress(file_out))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 7.28 s, sys: 531 ms, total: 7.81 s\n",
"Wall time: 1min 57s\n"
]
},
{
"data": {
"text/plain": [
"(None, None, None, None, None)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"dask.compute(*delayed)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:miniconda3-cesm2-marbl]",
"language": "python",
"name": "conda-env-miniconda3-cesm2-marbl-py"
},
"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.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment