Created
December 4, 2016 23:39
-
-
Save spencerkclark/158ddbd0b0df7de1332020429e4c97c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "Experimental NetCDFTimeIndex\n----------------------------" | |
}, | |
{ | |
"metadata": { | |
"collapsed": true, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "import xarray as xr\nimport numpy as np\n\nfrom pandas import Index\nfrom netCDF4 import netcdftime", | |
"execution_count": 1, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "def get_date_field(datetimes, field):\n \"\"\"This is implemented in cython in pandas; perhaps we \n could implement something similar for our purposes upstream\n in netcdftime, but as a proof of concept I'll just use\n this for now.\n \"\"\"\n a = []\n for d in datetimes:\n a.append(getattr(d, field))\n return np.array(a)\n\ndef _field_accessor(name, docstring=None):\n def f(self):\n values = self._data\n return get_date_field(values, name)\n \n f.__name__ = name\n f.__doc__ = docstring\n return property(f)\n\nclass NetCDFTimeIndex(Index):\n def __new__(cls, data):\n result = object.__new__(cls)\n result._data = np.array(data)\n return result\n \n year = _field_accessor('year', 'The year of the datetime')\n month = _field_accessor('month', 'The month of the datetime')\n day = _field_accessor('day', 'The days of the datetime')\n hour = _field_accessor('hour', 'The hours of the datetime')\n minute = _field_accessor('minute', 'The minutes of the datetime')\n second = _field_accessor('second', 'The seconds of the datetime')\n millisecond = _field_accessor('millisecond', 'The milliseconds of the datetime')\n microsecond = _field_accessor('microsecond', 'The microseconds of the datetime')\n \n def _maybe_convert_str_to_date(self, key):\n if isinstance(key, str):\n date_type = type(self._data[0]) # Is there a better way of doing this?\n return date_type(*netcdftime._parse_date(key))\n else:\n return key\n \n def get_loc(self, key, method=None, tolerance=None):\n \"\"\"Add support for ISO 8601 format string date specification\"\"\"\n return Index.get_loc(self, self._maybe_convert_str_to_date(key),\n method, tolerance)\n \n def slice_locs(self, start=None, end=None, step=None, kind=None):\n \"\"\"Add support for ISO 8601 format string date specification\"\"\"\n return Index.slice_locs(self, self._maybe_convert_str_to_date(start),\n self._maybe_convert_str_to_date(end),\n step, kind)", | |
"execution_count": 2, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "dates_0001 = [netcdftime.DatetimeAllLeap(1, m, 1) for m in range(1, 13)]\ndates_0002 = [netcdftime.DatetimeAllLeap(2, m, 1) for m in range(1, 13)]", | |
"execution_count": 3, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# Create a DataArray with a NetCDFTimeIndex as a coordinate\nda = xr.DataArray(np.arange(35, 35 + 24), coords=[NetCDFTimeIndex(dates_0001 + dates_0002)], dims=['time'])", | |
"execution_count": 4, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da", | |
"execution_count": 5, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (time: 24)>\narray([35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n 52, 53, 54, 55, 56, 57, 58])\nCoordinates:\n * time (time) object 1-01-01 00:00:00 1-02-01 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 5 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.time", | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray 'time' (time: 24)>\narray([netcdftime._netcdftime.DatetimeAllLeap(1, 1, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 2, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 3, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 4, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 5, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 6, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 7, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 8, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 9, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 10, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 11, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(1, 12, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 1, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 2, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 3, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 4, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 5, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 6, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 7, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 8, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 9, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 10, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 11, 1, 0, 0, 0, 0, -1, 1),\n netcdftime._netcdftime.DatetimeAllLeap(2, 12, 1, 0, 0, 0, 0, -1, 1)], dtype=object)\nCoordinates:\n * time (time) object 1-01-01 00:00:00 1-02-01 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 6 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.sel(time=slice(netcdftime.DatetimeAllLeap(1, 5, 1), netcdftime.DatetimeAllLeap(1, 7, 1)))", | |
"execution_count": 7, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (time: 3)>\narray([39, 40, 41])\nCoordinates:\n * time (time) object 1-05-01 00:00:00 1-06-01 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 7 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.sel(time=slice('0001-05-01', '0001-07-01'))", | |
"execution_count": 8, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (time: 3)>\narray([39, 40, 41])\nCoordinates:\n * time (time) object 1-05-01 00:00:00 1-06-01 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 8 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.groupby('time.month').mean('time')", | |
"execution_count": 9, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (month: 12)>\narray([ 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.,\n 52.])\nCoordinates:\n * month (month) int64 1 2 3 4 5 6 7 8 9 10 11 12" | |
}, | |
"metadata": {}, | |
"execution_count": 9 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.groupby('time.year').mean('time')", | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (year: 2)>\narray([ 40.5, 52.5])\nCoordinates:\n * year (year) int64 1 2" | |
}, | |
"metadata": {}, | |
"execution_count": 10 | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "The approach is calendar-agnostic\n---------------------------------" | |
}, | |
{ | |
"metadata": { | |
"collapsed": true, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# Try out a 360-day calendar\ndates_0001 = [netcdftime.Datetime360Day(1, m, 30) for m in range(1, 13)]\ndates_0002 = [netcdftime.Datetime360Day(2, m, 30) for m in range(1, 13)]", | |
"execution_count": 11, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": true, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da = xr.DataArray(np.arange(35, 35 + 24), coords=[NetCDFTimeIndex(dates_0001 + dates_0002)], dims=['time'])", | |
"execution_count": 12, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.sel(time=slice(netcdftime.Datetime360Day(1, 2, 1), netcdftime.Datetime360Day(1, 7, 1)))", | |
"execution_count": 13, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (time: 5)>\narray([36, 37, 38, 39, 40])\nCoordinates:\n * time (time) object 1-02-30 00:00:00 1-03-30 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 13 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.sel(time=slice('0001-02-01', '0001-07-01'))", | |
"execution_count": 14, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (time: 5)>\narray([36, 37, 38, 39, 40])\nCoordinates:\n * time (time) object 1-02-30 00:00:00 1-03-30 00:00:00 ..." | |
}, | |
"metadata": {}, | |
"execution_count": 14 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.groupby('time.month').mean('time')", | |
"execution_count": 15, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (month: 12)>\narray([ 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.,\n 52.])\nCoordinates:\n * month (month) int64 1 2 3 4 5 6 7 8 9 10 11 12" | |
}, | |
"metadata": {}, | |
"execution_count": 15 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": false, | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "da.groupby('time.year').mean('time')", | |
"execution_count": 16, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "<xarray.DataArray (year: 2)>\narray([ 40.5, 52.5])\nCoordinates:\n * year (year) int64 1 2" | |
}, | |
"metadata": {}, | |
"execution_count": 16 | |
} | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"name": "python2", | |
"display_name": "Python 2", | |
"language": "python" | |
}, | |
"language_info": { | |
"mimetype": "text/x-python", | |
"nbconvert_exporter": "python", | |
"name": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.12", | |
"file_extension": ".py", | |
"codemirror_mode": { | |
"version": 2, | |
"name": "ipython" | |
} | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment