├── LICENSE ├── OldNotebooks ├── XArray2_MissingDataCombining.ipynb ├── XArrayAndRasterio-Copy1.ipynb ├── XArrayAndRasterio.ipynb ├── XArrayDaskGraphsEtc.ipynb ├── XArray_Basics.ipynb ├── XarrayAndDask_MultipleNCFiles.ipynb ├── XarrayAndDask_OneNCFile.ipynb ├── XarrayAndRasterstats.ipynb ├── XarrayDtypesIssues.ipynb └── XarrayForVFPoC.ipynb ├── README.md └── rasterio_to_xarray.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Robin Wilson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OldNotebooks/XArray2_MissingDataCombining.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "import xarray as xr" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": { 29 | "collapsed": true 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "%matplotlib inline" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 4, 39 | "metadata": { 40 | "collapsed": true 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "from matplotlib.pyplot import *" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 5, 50 | "metadata": { 51 | "collapsed": true 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "from datetime import datetime" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 6, 61 | "metadata": { 62 | "collapsed": false 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "data = np.random.rand(3, 10)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 7, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "data": { 78 | "text/plain": [ 79 | "(3, 10)" 80 | ] 81 | }, 82 | "execution_count": 7, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "data.shape" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 22, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/plain": [ 101 | "array([[ nan, 0.55589243, 0.11753801, 0.08013517, 0.30560374,\n", 102 | " nan, 0.20962094, 0.23187731, 0.06316331, 0.57970108],\n", 103 | " [ 0.38085612, 0.16466536, nan, 0.77754006, 0.46032132,\n", 104 | " 0.69870195, 0.75686837, 0.45285803, 0.22131184, 0.70564802],\n", 105 | " [ 0.48013034, 0.56288659, 0.57884486, 0.76661368, 0.59727641,\n", 106 | " nan, 0.7725577 , nan, 0.50381469, nan]])" 107 | ] 108 | }, 109 | "execution_count": 22, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "data[data > 0.8] = np.nan\n", 116 | "data" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 23, 122 | "metadata": { 123 | "collapsed": false 124 | }, 125 | "outputs": [ 126 | { 127 | "data": { 128 | "text/plain": [ 129 | "\n", 130 | "array([[ nan, 0.55589243, 0.11753801, 0.08013517, 0.30560374,\n", 131 | " nan, 0.20962094, 0.23187731, 0.06316331, 0.57970108],\n", 132 | " [ 0.38085612, 0.16466536, nan, 0.77754006, 0.46032132,\n", 133 | " 0.69870195, 0.75686837, 0.45285803, 0.22131184, 0.70564802],\n", 134 | " [ 0.48013034, 0.56288659, 0.57884486, 0.76661368, 0.59727641,\n", 135 | " nan, 0.7725577 , nan, 0.50381469, nan]])\n", 136 | "Coordinates:\n", 137 | " time datetime64[ns] 2010-01-03\n", 138 | " * x (x) int64 10 20 30\n", 139 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9" 140 | ] 141 | }, 142 | "execution_count": 23, 143 | "metadata": {}, 144 | "output_type": "execute_result" 145 | } 146 | ], 147 | "source": [ 148 | "a = xr.DataArray(data, dims=['x', 'y'], coords={'x': [10, 20, 30], 'time':datetime(2010, 1, 3)})\n", 149 | "a" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 24, 155 | "metadata": { 156 | "collapsed": false 157 | }, 158 | "outputs": [], 159 | "source": [ 160 | "datab = data.copy()\n", 161 | "datab[datab < .5] = np.nan" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 25, 167 | "metadata": { 168 | "collapsed": false 169 | }, 170 | "outputs": [ 171 | { 172 | "data": { 173 | "text/plain": [ 174 | "array([[ nan, 0.55589243, nan, nan, nan,\n", 175 | " nan, nan, nan, nan, 0.57970108],\n", 176 | " [ nan, nan, nan, 0.77754006, nan,\n", 177 | " 0.69870195, 0.75686837, nan, nan, 0.70564802],\n", 178 | " [ nan, 0.56288659, 0.57884486, 0.76661368, 0.59727641,\n", 179 | " nan, 0.7725577 , nan, 0.50381469, nan]])" 180 | ] 181 | }, 182 | "execution_count": 25, 183 | "metadata": {}, 184 | "output_type": "execute_result" 185 | } 186 | ], 187 | "source": [ 188 | "datab" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 26, 194 | "metadata": { 195 | "collapsed": true 196 | }, 197 | "outputs": [], 198 | "source": [ 199 | "b = xr.DataArray(datab, dims=['x', 'y'], coords={'x': [10, 20, 30], 'time':datetime(2010, 1, 4)})" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 27, 205 | "metadata": { 206 | "collapsed": false 207 | }, 208 | "outputs": [], 209 | "source": [ 210 | "comb = xr.concat([a, b], 'time')" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 29, 216 | "metadata": { 217 | "collapsed": false 218 | }, 219 | "outputs": [ 220 | { 221 | "data": { 222 | "text/plain": [ 223 | "\n", 224 | "array([[0, 2, 1, 1, 1, 0, 1, 1, 1, 2],\n", 225 | " [1, 1, 0, 2, 1, 2, 2, 1, 1, 2],\n", 226 | " [1, 2, 2, 2, 2, 0, 2, 0, 2, 0]])\n", 227 | "Coordinates:\n", 228 | " * x (x) int64 10 20 30\n", 229 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9" 230 | ] 231 | }, 232 | "execution_count": 29, 233 | "metadata": {}, 234 | "output_type": "execute_result" 235 | } 236 | ], 237 | "source": [ 238 | "comb.count(dim='time')" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": 31, 244 | "metadata": { 245 | "collapsed": false 246 | }, 247 | "outputs": [ 248 | { 249 | "data": { 250 | "text/plain": [ 251 | "\n", 252 | "array([[ nan, 0.55589243, 0.11753801, 0.08013517, 0.30560374,\n", 253 | " nan, 0.20962094, 0.23187731, 0.06316331, 0.57970108],\n", 254 | " [ 0.38085612, 0.16466536, nan, 0.77754006, 0.46032132,\n", 255 | " 0.69870195, 0.75686837, 0.45285803, 0.22131184, 0.70564802],\n", 256 | " [ 0.48013034, 0.56288659, 0.57884486, 0.76661368, 0.59727641,\n", 257 | " nan, 0.7725577 , nan, 0.50381469, nan]])\n", 258 | "Coordinates:\n", 259 | " * x (x) int64 10 20 30\n", 260 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9" 261 | ] 262 | }, 263 | "execution_count": 31, 264 | "metadata": {}, 265 | "output_type": "execute_result" 266 | } 267 | ], 268 | "source": [ 269 | "comb.max(dim='time')" 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 33, 275 | "metadata": { 276 | "collapsed": false 277 | }, 278 | "outputs": [ 279 | { 280 | "data": { 281 | "text/plain": [ 282 | "\n", 283 | "array([[[ 0.6058128 , 0.41439131, 0.57819417, 0.11189831, 0.07093284,\n", 284 | " 0.49545013, 0.00960583, 0.83443594, 0.19037937, 0.15308206],\n", 285 | " [ 0.26699744, 0.59888543, 0.15972862, 0.19820866, 0.45922169,\n", 286 | " 0.21900277, 0.5773666 , 0.73640294, 0.07778405, 0.77081377],\n", 287 | " [ 0.31449483, 0.22698163, 0.94639217, 0.41111678, 0.60665371,\n", 288 | " 0.75854892, 0.62022036, 0.67855218, 0.24051055, 0.24616162]],\n", 289 | "\n", 290 | " [[ 0.6058128 , 0.41439131, 0.57819417, 0.11189831, 0.07093284,\n", 291 | " 0.49545013, 0.00960583, 0.83443594, 0.19037937, 0.15308206],\n", 292 | " [ 0.26699744, 0.59888543, 0.15972862, 0.19820866, 0.45922169,\n", 293 | " 0.21900277, 0.5773666 , 0.73640294, 0.07778405, 0.77081377],\n", 294 | " [ 0.31449483, 0.22698163, 0.94639217, 0.41111678, 0.60665371,\n", 295 | " 0.75854892, 0.62022036, 0.67855218, 0.24051055, 0.24616162]],\n", 296 | "\n", 297 | " [[ 0.6058128 , 0.41439131, 0.57819417, 0.11189831, 0.07093284,\n", 298 | " 0.49545013, 0.00960583, 0.83443594, 0.19037937, 0.15308206],\n", 299 | " [ 0.26699744, 0.59888543, 0.15972862, 0.19820866, 0.45922169,\n", 300 | " 0.21900277, 0.5773666 , 0.73640294, 0.07778405, 0.77081377],\n", 301 | " [ 0.31449483, 0.22698163, 0.94639217, 0.41111678, 0.60665371,\n", 302 | " 0.75854892, 0.62022036, 0.67855218, 0.24051055, 0.24616162]],\n", 303 | "\n", 304 | " [[ 0.6058128 , 0.41439131, 0.57819417, 0.11189831, 0.07093284,\n", 305 | " 0.49545013, 0.00960583, 0.83443594, 0.19037937, 0.15308206],\n", 306 | " [ 0.26699744, 0.59888543, 0.15972862, 0.19820866, 0.45922169,\n", 307 | " 0.21900277, 0.5773666 , 0.73640294, 0.07778405, 0.77081377],\n", 308 | " [ 0.31449483, 0.22698163, 0.94639217, 0.41111678, 0.60665371,\n", 309 | " 0.75854892, 0.62022036, 0.67855218, 0.24051055, 0.24616162]]])\n", 310 | "Coordinates:\n", 311 | " * x (x) int64 10 20 30\n", 312 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9\n", 313 | " * day (day) int64 3 4 5 6" 314 | ] 315 | }, 316 | "execution_count": 33, 317 | "metadata": {}, 318 | "output_type": "execute_result" 319 | } 320 | ], 321 | "source": [ 322 | "comb.groupby('time.day').mean(dim='time')" 323 | ] 324 | }, 325 | { 326 | "cell_type": "code", 327 | "execution_count": null, 328 | "metadata": { 329 | "collapsed": false 330 | }, 331 | "outputs": [], 332 | "source": [ 333 | "ds = comb.to_dataset(name='test')" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": null, 339 | "metadata": { 340 | "collapsed": true 341 | }, 342 | "outputs": [], 343 | "source": [ 344 | "ds.to_netcdf('test.nc')" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": null, 350 | "metadata": { 351 | "collapsed": true 352 | }, 353 | "outputs": [], 354 | "source": [ 355 | "!mkdir multifile" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "metadata": { 362 | "collapsed": true 363 | }, 364 | "outputs": [], 365 | "source": [ 366 | "!cp test.nc multifile/test2.nc" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": { 373 | "collapsed": false 374 | }, 375 | "outputs": [], 376 | "source": [ 377 | "ds = xr.open_mfdataset('multifile/*.nc', concat_dim='time')" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": null, 383 | "metadata": { 384 | "collapsed": false 385 | }, 386 | "outputs": [], 387 | "source": [ 388 | "ds['time'].values" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": null, 394 | "metadata": { 395 | "collapsed": false 396 | }, 397 | "outputs": [], 398 | "source": [ 399 | "ds.sel(time='2010-01-03')" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": null, 405 | "metadata": { 406 | "collapsed": false 407 | }, 408 | "outputs": [], 409 | "source": [ 410 | "da = ds['test']" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": null, 416 | "metadata": { 417 | "collapsed": false 418 | }, 419 | "outputs": [], 420 | "source": [ 421 | "da.sel(time='2010-01-03').mean(dim='time').plot()" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": null, 427 | "metadata": { 428 | "collapsed": true 429 | }, 430 | "outputs": [], 431 | "source": [] 432 | } 433 | ], 434 | "metadata": { 435 | "kernelspec": { 436 | "display_name": "Python 3", 437 | "language": "python", 438 | "name": "python3" 439 | }, 440 | "language_info": { 441 | "codemirror_mode": { 442 | "name": "ipython", 443 | "version": 3 444 | }, 445 | "file_extension": ".py", 446 | "mimetype": "text/x-python", 447 | "name": "python", 448 | "nbconvert_exporter": "python", 449 | "pygments_lexer": "ipython3", 450 | "version": "3.5.1" 451 | } 452 | }, 453 | "nbformat": 4, 454 | "nbformat_minor": 0 455 | } 456 | -------------------------------------------------------------------------------- /OldNotebooks/XArrayAndRasterio-Copy1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 19, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "import xarray as xr\n", 13 | "import rasterio\n", 14 | "%matplotlib inline\n", 15 | "from matplotlib.pyplot import *\n", 16 | "from glob import glob\n", 17 | "import os\n", 18 | "import datetime\n", 19 | "\n", 20 | "from rasterio_to_xarray import rasterio_to_xarray, xarray_to_rasterio" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 20, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def maiac_file_to_da(filename):\n", 32 | " da = rasterio_to_xarray(filename)\n", 33 | " \n", 34 | " da.values[da.values == -28672] = np.nan\n", 35 | " da.values[da.values == 0] = np.nan\n", 36 | " \n", 37 | " da.values = da.values.astype(np.float64)\n", 38 | " \n", 39 | " time_str = os.path.basename(filename)[17:-13]\n", 40 | " time_obj = datetime.datetime.strptime(time_str, '%Y%j%H%M')\n", 41 | " da.coords['time'] = time_obj\n", 42 | " \n", 43 | " return da" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 21, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "files = glob('2014_All/*_proj.tif')" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 22, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "list_of_das = map(maiac_file_to_da, files)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 23, 71 | "metadata": { 72 | "collapsed": false 73 | }, 74 | "outputs": [ 75 | { 76 | "name": "stderr", 77 | "output_type": "stream", 78 | "text": [ 79 | "/Users/robin/code/MAIACProcessing/rasterio_to_xarray.py:29: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.\n", 80 | " data = np.where(data == src.nodata, np.nan, data)\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "res = xr.concat(list_of_das, 'time')" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 24, 91 | "metadata": { 92 | "collapsed": true 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "daily = res.resample('D', dim='time', how='max')" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 25, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "overall_mean = daily.mean(dim='time', keep_attrs=True)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 26, 113 | "metadata": { 114 | "collapsed": true 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "xarray_to_rasterio(overall_mean, 'test_overallmean_nodask_f64.tif')" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "collapsed": true 126 | }, 127 | "outputs": [], 128 | "source": [] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "metadata": { 134 | "collapsed": true 135 | }, 136 | "outputs": [], 137 | "source": [] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": { 143 | "collapsed": true 144 | }, 145 | "outputs": [], 146 | "source": [ 147 | "m = r.mean(dim='date')" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "metadata": { 154 | "collapsed": false 155 | }, 156 | "outputs": [], 157 | "source": [ 158 | "xarray_to_rasterio(m, 'test_mnotattrs.tif')" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": { 165 | "collapsed": true 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "xarray_to_rasterio(overall_mean, 'test_overallmean.tif')" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": { 176 | "collapsed": true 177 | }, 178 | "outputs": [], 179 | "source": [ 180 | "import pandas as pd" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": { 187 | "collapsed": false 188 | }, 189 | "outputs": [], 190 | "source": [ 191 | "r['date'] = pd.to_datetime(r['date'])" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": null, 197 | "metadata": { 198 | "collapsed": false 199 | }, 200 | "outputs": [], 201 | "source": [ 202 | "seasonal = r.groupby('date.month').mean(dim='date')" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": { 209 | "collapsed": false 210 | }, 211 | "outputs": [], 212 | "source": [ 213 | "[dim for dim in seasonal.dims if dim not in ['y', 'x']]" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": { 220 | "collapsed": false 221 | }, 222 | "outputs": [], 223 | "source": [ 224 | "seasonal.coords['month'].values" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": { 231 | "collapsed": true 232 | }, 233 | "outputs": [], 234 | "source": [ 235 | "xarray_to_rasterio(seasonal, 'test_seasonal.tif')" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": { 242 | "collapsed": false 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "figure(figsize=(20, 12))\n", 247 | "seasonal.plot(col='month', robust=True)" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": { 254 | "collapsed": false, 255 | "scrolled": false 256 | }, 257 | "outputs": [], 258 | "source": [ 259 | "figure(figsize=(20, 12))\n", 260 | "mr.plot.pcolormesh(robust=True)" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "metadata": { 267 | "collapsed": false 268 | }, 269 | "outputs": [], 270 | "source": [ 271 | "res.plot.pcolormesh??" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": null, 277 | "metadata": { 278 | "collapsed": false 279 | }, 280 | "outputs": [], 281 | "source": [ 282 | "mr.sel(x=slice(0, 600000), y=slice(mr.y.min(), mr.y.max()))" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": null, 288 | "metadata": { 289 | "collapsed": false 290 | }, 291 | "outputs": [], 292 | "source": [ 293 | "res.groupby('time.month').mean(dim='time')" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "metadata": { 300 | "collapsed": false 301 | }, 302 | "outputs": [], 303 | "source": [ 304 | "overall_count = r.count(dim='date')" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": null, 310 | "metadata": { 311 | "collapsed": false 312 | }, 313 | "outputs": [], 314 | "source": [ 315 | "overall_count.isel(x=slice(1050,1150), y=slice(1000,1100)).plot(robust=True)" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": null, 321 | "metadata": { 322 | "collapsed": false 323 | }, 324 | "outputs": [], 325 | "source": [ 326 | "overall_count.plot.hist()" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "metadata": { 333 | "collapsed": false 334 | }, 335 | "outputs": [], 336 | "source": [ 337 | "overall_mean.isel(x=slice(1050,1150), y=slice(1000,1100)).plot(robust=True)" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "metadata": { 344 | "collapsed": false 345 | }, 346 | "outputs": [], 347 | "source": [ 348 | "overall_mean.attrs" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": { 355 | "collapsed": false 356 | }, 357 | "outputs": [], 358 | "source": [ 359 | "r.coords['y'].max()" 360 | ] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": null, 365 | "metadata": { 366 | "collapsed": false 367 | }, 368 | "outputs": [], 369 | "source": [ 370 | "r.sel(x=439480, y=138506, tolerance=1000, method='nearest').to_dataframe(name='data')" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": null, 376 | "metadata": { 377 | "collapsed": true 378 | }, 379 | "outputs": [], 380 | "source": [] 381 | } 382 | ], 383 | "metadata": { 384 | "_draft": { 385 | "nbviewer_url": "https://gist.github.com/a4f1a732bbdfeeffc56d1c72e0cd8ee7" 386 | }, 387 | "gist": { 388 | "data": { 389 | "description": "XArrayAndRasterio2.ipynb", 390 | "public": true 391 | }, 392 | "id": "a4f1a732bbdfeeffc56d1c72e0cd8ee7" 393 | }, 394 | "kernelspec": { 395 | "display_name": "Python 3", 396 | "language": "python", 397 | "name": "python3" 398 | }, 399 | "language_info": { 400 | "codemirror_mode": { 401 | "name": "ipython", 402 | "version": 3 403 | }, 404 | "file_extension": ".py", 405 | "mimetype": "text/x-python", 406 | "name": "python", 407 | "nbconvert_exporter": "python", 408 | "pygments_lexer": "ipython3", 409 | "version": "3.5.1" 410 | } 411 | }, 412 | "nbformat": 4, 413 | "nbformat_minor": 0 414 | } 415 | -------------------------------------------------------------------------------- /OldNotebooks/XArrayAndRasterio.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "import xarray as xr\n", 13 | "import rasterio\n", 14 | "%matplotlib inline\n", 15 | "from matplotlib.pyplot import *\n", 16 | "from glob import glob\n", 17 | "import os\n", 18 | "import datetime\n", 19 | "\n", 20 | "from rasterio_to_xarray import rasterio_to_xarray, xarray_to_rasterio" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": false 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "x = rasterio_to_xarray('/Users/robin/ownCloud/HOTBAR/Annie/MAIACAAOT.h00v01.20140031240.hdf_proj.tif')" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 4, 37 | "metadata": { 38 | "collapsed": false 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "ds = x.to_dataset(name='data')" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 5, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [], 52 | "source": [ 53 | "ds.to_netcdf('blah5.nc')" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 8, 59 | "metadata": { 60 | "collapsed": false 61 | }, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "text/plain": [ 66 | "OrderedDict([('crs', '+init=epsg:27700'),\n", 67 | " ('affine',\n", 68 | " (-947639.6305106478,\n", 69 | " 1256.5430440955893,\n", 70 | " 0.0,\n", 71 | " 1429277.8120091767,\n", 72 | " 0.0,\n", 73 | " -1256.5430440955893))])" 74 | ] 75 | }, 76 | "execution_count": 8, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "x.attrs" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 6, 88 | "metadata": { 89 | "collapsed": true 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "newds = xr.open_dataset('blah5.nc')" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 11, 99 | "metadata": { 100 | "collapsed": false 101 | }, 102 | "outputs": [ 103 | { 104 | "data": { 105 | "text/plain": [ 106 | "'/Users/robin/code/MAIACProcessing'" 107 | ] 108 | }, 109 | "execution_count": 11, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "pwd" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 10, 121 | "metadata": { 122 | "collapsed": false 123 | }, 124 | "outputs": [], 125 | "source": [ 126 | "xarray_to_rasterio(newds['data'], 'attrstest.tif')" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": { 133 | "collapsed": true 134 | }, 135 | "outputs": [], 136 | "source": [ 137 | "def maiac_file_to_da(filename):\n", 138 | " da = rasterio_to_xarray(filename)\n", 139 | " \n", 140 | " da.values[da.values == -28672] = np.nan\n", 141 | " da.values[da.values == 0] = np.nan\n", 142 | " \n", 143 | " time_str = os.path.basename(filename)[17:-13]\n", 144 | " time_obj = datetime.datetime.strptime(time_str, '%Y%j%H%M')\n", 145 | " da.coords['time'] = time_obj\n", 146 | " \n", 147 | " return da" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "metadata": { 154 | "collapsed": false 155 | }, 156 | "outputs": [], 157 | "source": [ 158 | "files = glob('2014/*_proj.tif')" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [], 168 | "source": [ 169 | "maiac_file_to_da(files[0])" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": { 176 | "collapsed": false 177 | }, 178 | "outputs": [], 179 | "source": [ 180 | "list_of_das = map(maiac_file_to_da, files)" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": { 187 | "collapsed": false 188 | }, 189 | "outputs": [], 190 | "source": [ 191 | "res = xr.concat(list_of_das, 'time')" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": null, 197 | "metadata": { 198 | "collapsed": false 199 | }, 200 | "outputs": [], 201 | "source": [ 202 | "res" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": { 209 | "collapsed": false 210 | }, 211 | "outputs": [], 212 | "source": [ 213 | "r = res.groupby('time.date').max(dim='time')" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": { 220 | "collapsed": false 221 | }, 222 | "outputs": [], 223 | "source": [ 224 | "overall_mean = r.mean(dim='date', keep_attrs=True)" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": { 231 | "collapsed": true 232 | }, 233 | "outputs": [], 234 | "source": [ 235 | "m = r.mean(dim='date')" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": { 242 | "collapsed": false 243 | }, 244 | "outputs": [], 245 | "source": [ 246 | "xarray_to_rasterio(m, 'test_mnotattrs.tif')" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "metadata": { 253 | "collapsed": true 254 | }, 255 | "outputs": [], 256 | "source": [ 257 | "xarray_to_rasterio(overall_mean, 'test_overallmean.tif')" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": null, 263 | "metadata": { 264 | "collapsed": true 265 | }, 266 | "outputs": [], 267 | "source": [ 268 | "import pandas as pd" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": null, 274 | "metadata": { 275 | "collapsed": false 276 | }, 277 | "outputs": [], 278 | "source": [ 279 | "r['date'] = pd.to_datetime(r['date'])" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "collapsed": false 287 | }, 288 | "outputs": [], 289 | "source": [ 290 | "seasonal = r.groupby('date.month').mean(dim='date')" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": null, 296 | "metadata": { 297 | "collapsed": false 298 | }, 299 | "outputs": [], 300 | "source": [ 301 | "[dim for dim in seasonal.dims if dim not in ['y', 'x']]" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "metadata": { 308 | "collapsed": false 309 | }, 310 | "outputs": [], 311 | "source": [ 312 | "seasonal.coords['month'].values" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": null, 318 | "metadata": { 319 | "collapsed": true 320 | }, 321 | "outputs": [], 322 | "source": [ 323 | "xarray_to_rasterio(seasonal, 'test_seasonal.tif')" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": null, 329 | "metadata": { 330 | "collapsed": false 331 | }, 332 | "outputs": [], 333 | "source": [ 334 | "figure(figsize=(20, 12))\n", 335 | "seasonal.plot(col='month', robust=True)" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": null, 341 | "metadata": { 342 | "collapsed": false, 343 | "scrolled": false 344 | }, 345 | "outputs": [], 346 | "source": [ 347 | "figure(figsize=(20, 12))\n", 348 | "mr.plot.pcolormesh(robust=True)" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": { 355 | "collapsed": false 356 | }, 357 | "outputs": [], 358 | "source": [ 359 | "res.plot.pcolormesh??" 360 | ] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": null, 365 | "metadata": { 366 | "collapsed": false 367 | }, 368 | "outputs": [], 369 | "source": [ 370 | "mr.sel(x=slice(0, 600000), y=slice(mr.y.min(), mr.y.max()))" 371 | ] 372 | }, 373 | { 374 | "cell_type": "code", 375 | "execution_count": null, 376 | "metadata": { 377 | "collapsed": false 378 | }, 379 | "outputs": [], 380 | "source": [ 381 | "res.groupby('time.month').mean(dim='time')" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": null, 387 | "metadata": { 388 | "collapsed": false 389 | }, 390 | "outputs": [], 391 | "source": [ 392 | "overall_count = r.count(dim='date')" 393 | ] 394 | }, 395 | { 396 | "cell_type": "code", 397 | "execution_count": null, 398 | "metadata": { 399 | "collapsed": false 400 | }, 401 | "outputs": [], 402 | "source": [ 403 | "overall_count.isel(x=slice(1050,1150), y=slice(1000,1100)).plot(robust=True)" 404 | ] 405 | }, 406 | { 407 | "cell_type": "code", 408 | "execution_count": null, 409 | "metadata": { 410 | "collapsed": false 411 | }, 412 | "outputs": [], 413 | "source": [ 414 | "overall_count.plot.hist()" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": null, 420 | "metadata": { 421 | "collapsed": false 422 | }, 423 | "outputs": [], 424 | "source": [ 425 | "overall_mean.isel(x=slice(1050,1150), y=slice(1000,1100)).plot(robust=True)" 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "execution_count": null, 431 | "metadata": { 432 | "collapsed": false 433 | }, 434 | "outputs": [], 435 | "source": [ 436 | "overall_mean.attrs" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": null, 442 | "metadata": { 443 | "collapsed": false 444 | }, 445 | "outputs": [], 446 | "source": [ 447 | "r.coords['y'].max()" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": null, 453 | "metadata": { 454 | "collapsed": false 455 | }, 456 | "outputs": [], 457 | "source": [ 458 | "r.sel(x=439480, y=138506, tolerance=1000, method='nearest').to_dataframe(name='data')" 459 | ] 460 | }, 461 | { 462 | "cell_type": "code", 463 | "execution_count": null, 464 | "metadata": { 465 | "collapsed": true 466 | }, 467 | "outputs": [], 468 | "source": [] 469 | } 470 | ], 471 | "metadata": { 472 | "_draft": { 473 | "nbviewer_url": "https://gist.github.com/a4f1a732bbdfeeffc56d1c72e0cd8ee7" 474 | }, 475 | "gist": { 476 | "data": { 477 | "description": "XArrayAndRasterio2.ipynb", 478 | "public": true 479 | }, 480 | "id": "a4f1a732bbdfeeffc56d1c72e0cd8ee7" 481 | }, 482 | "kernelspec": { 483 | "display_name": "Python 3", 484 | "language": "python", 485 | "name": "python3" 486 | }, 487 | "language_info": { 488 | "codemirror_mode": { 489 | "name": "ipython", 490 | "version": 3 491 | }, 492 | "file_extension": ".py", 493 | "mimetype": "text/x-python", 494 | "name": "python", 495 | "nbconvert_exporter": "python", 496 | "pygments_lexer": "ipython3", 497 | "version": "3.5.1" 498 | } 499 | }, 500 | "nbformat": 4, 501 | "nbformat_minor": 0 502 | } 503 | -------------------------------------------------------------------------------- /OldNotebooks/XArray_Basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "import xarray as xr" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": { 29 | "collapsed": true 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "%matplotlib inline" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 4, 39 | "metadata": { 40 | "collapsed": true 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "from matplotlib.pyplot import *" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 5, 50 | "metadata": { 51 | "collapsed": true 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "from datetime import datetime" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 6, 61 | "metadata": { 62 | "collapsed": false 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "data = np.random.rand(3, 10)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 7, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "data": { 78 | "text/plain": [ 79 | "" 80 | ] 81 | }, 82 | "execution_count": 7, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | }, 86 | { 87 | "data": { 88 | "image/png": "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\n+wUIAs4DWq0x7AAAAABJRU5ErkJggg==\n", 89 | "text/plain": [ 90 | "" 91 | ] 92 | }, 93 | "metadata": {}, 94 | "output_type": "display_data" 95 | } 96 | ], 97 | "source": [ 98 | "imshow(data)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 8, 104 | "metadata": { 105 | "collapsed": false 106 | }, 107 | "outputs": [ 108 | { 109 | "data": { 110 | "text/plain": [ 111 | "(3, 10)" 112 | ] 113 | }, 114 | "execution_count": 8, 115 | "metadata": {}, 116 | "output_type": "execute_result" 117 | } 118 | ], 119 | "source": [ 120 | "data.shape" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 9, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/plain": [ 133 | "\n", 134 | "array([[ 0.39056321, 0.82626331, 0.43783802, 0.2440198 , 0.14751531,\n", 135 | " 0.84863518, 0.12155338, 0.67713525, 0.98485161, 0.26310522],\n", 136 | " [ 0.82942071, 0.88934761, 0.89404326, 0.61841384, 0.3807382 ,\n", 137 | " 0.50075306, 0.42951757, 0.69629503, 0.12563943, 0.11668283],\n", 138 | " [ 0.92739738, 0.6011591 , 0.09274587, 0.07512127, 0.25561684,\n", 139 | " 0.85396064, 0.96109693, 0.69063447, 0.81210857, 0.23312271]])\n", 140 | "Coordinates:\n", 141 | " date datetime64[ns] 2013-03-16\n", 142 | " * y (y) \n", 178 | "array([[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 179 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 180 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 181 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 182 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 183 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]])\n", 184 | "Coordinates:\n", 185 | " date datetime64[ns] 2013-03-16\n", 186 | " * y (y) \n", 211 | "array([ 0.82942071, 0.88934761, 0.89404326, 0.61841384, 0.3807382 ,\n", 212 | " 0.50075306, 0.42951757, 0.69629503, 0.12563943, 0.11668283])\n", 213 | "Coordinates:\n", 214 | " date datetime64[ns] 2013-03-16\n", 215 | " y \n", 239 | "array([[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 240 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 241 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 242 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 243 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 244 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]])\n", 245 | "Coordinates:\n", 246 | " time datetime64[ns] 2010-01-03\n", 247 | " * x (x) int64 0 1 2\n", 248 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9" 249 | ] 250 | }, 251 | "execution_count": 23, 252 | "metadata": {}, 253 | "output_type": "execute_result" 254 | } 255 | ], 256 | "source": [ 257 | "a = xr.DataArray(data, dims=['x', 'y'], coords={'time':datetime(2010, 1, 3)})\n", 258 | "a" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": 24, 264 | "metadata": { 265 | "collapsed": false 266 | }, 267 | "outputs": [], 268 | "source": [ 269 | "b = xr.DataArray(data, dims=['x', 'y'], coords={'time':datetime(2010, 1, 4)})\n", 270 | "c = xr.DataArray(data, dims=['x', 'y'], coords={'time':datetime(2010, 1, 5)})\n", 271 | "d = xr.DataArray(data, dims=['x', 'y'], coords={'time':datetime(2010, 1, 6)})\n" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 25, 277 | "metadata": { 278 | "collapsed": false 279 | }, 280 | "outputs": [], 281 | "source": [ 282 | "comb = xr.concat([a, b, c, d], 'time')" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": 26, 288 | "metadata": { 289 | "collapsed": false 290 | }, 291 | "outputs": [ 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "\n", 296 | "array([[[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 297 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 298 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 299 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 300 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 301 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]],\n", 302 | "\n", 303 | " [[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 304 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 305 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 306 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 307 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 308 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]],\n", 309 | "\n", 310 | " [[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 311 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 312 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 313 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 314 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 315 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]],\n", 316 | "\n", 317 | " [[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 318 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 319 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 320 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 321 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 322 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]]])\n", 323 | "Coordinates:\n", 324 | " * x (x) int64 0 1 2\n", 325 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9\n", 326 | " * time (time) datetime64[ns] 2010-01-03 2010-01-04 2010-01-05 2010-01-06" 327 | ] 328 | }, 329 | "execution_count": 26, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | } 333 | ], 334 | "source": [ 335 | "comb" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 28, 341 | "metadata": { 342 | "collapsed": false 343 | }, 344 | "outputs": [ 345 | { 346 | "data": { 347 | "text/plain": [ 348 | "\n", 349 | "array([[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 350 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 351 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 352 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 353 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 354 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]])\n", 355 | "Coordinates:\n", 356 | " * x (x) int64 0 1 2\n", 357 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9" 358 | ] 359 | }, 360 | "execution_count": 28, 361 | "metadata": {}, 362 | "output_type": "execute_result" 363 | } 364 | ], 365 | "source": [ 366 | "comb.mean(dim='time')" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": 35, 372 | "metadata": { 373 | "collapsed": false 374 | }, 375 | "outputs": [ 376 | { 377 | "data": { 378 | "text/plain": [ 379 | "\n", 380 | "array([[[ 0.0429289 , 0.33938654, 0.21674902, 0.22753095, 0.68395407,\n", 381 | " 0.39094687, 0.77467623, 0.51696466, 0.75943175, 0.38275408],\n", 382 | " [ 0.02639399, 0.94732725, 0.49094081, 0.90909402, 0.65737675,\n", 383 | " 0.07184436, 0.66002162, 0.53055385, 0.78551893, 0.95129523],\n", 384 | " [ 0.53927173, 0.85074663, 0.63138561, 0.31078671, 0.31914326,\n", 385 | " 0.73700543, 0.55976134, 0.60737377, 0.54293409, 0.75794238]]])\n", 386 | "Coordinates:\n", 387 | " * x (x) int64 0 1 2\n", 388 | " * y (y) int64 0 1 2 3 4 5 6 7 8 9\n", 389 | " * month (month) int64 1" 390 | ] 391 | }, 392 | "execution_count": 35, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "comb.groupby('time.month').mean(dim='time')" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 33, 404 | "metadata": { 405 | "collapsed": false 406 | }, 407 | "outputs": [ 408 | { 409 | "data": { 410 | "text/plain": [ 411 | "{1: [0, 1, 2, 3]}" 412 | ] 413 | }, 414 | "execution_count": 33, 415 | "metadata": {}, 416 | "output_type": "execute_result" 417 | } 418 | ], 419 | "source": [ 420 | "g.groups" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": null, 426 | "metadata": { 427 | "collapsed": false 428 | }, 429 | "outputs": [], 430 | "source": [ 431 | "ds = comb.to_dataset(name='test')" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": null, 437 | "metadata": { 438 | "collapsed": true 439 | }, 440 | "outputs": [], 441 | "source": [ 442 | "ds.to_netcdf('test.nc')" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": null, 448 | "metadata": { 449 | "collapsed": true 450 | }, 451 | "outputs": [], 452 | "source": [ 453 | "!mkdir multifile" 454 | ] 455 | }, 456 | { 457 | "cell_type": "code", 458 | "execution_count": null, 459 | "metadata": { 460 | "collapsed": true 461 | }, 462 | "outputs": [], 463 | "source": [ 464 | "!cp test.nc multifile/test2.nc" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": { 471 | "collapsed": false 472 | }, 473 | "outputs": [], 474 | "source": [ 475 | "ds = xr.open_mfdataset('multifile/*.nc', concat_dim='time')" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "metadata": { 482 | "collapsed": false 483 | }, 484 | "outputs": [], 485 | "source": [ 486 | "ds['time'].values" 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": null, 492 | "metadata": { 493 | "collapsed": false 494 | }, 495 | "outputs": [], 496 | "source": [ 497 | "ds.sel(time='2010-01-03')" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": null, 503 | "metadata": { 504 | "collapsed": false 505 | }, 506 | "outputs": [], 507 | "source": [ 508 | "da = ds['test']" 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": null, 514 | "metadata": { 515 | "collapsed": false 516 | }, 517 | "outputs": [], 518 | "source": [ 519 | "da.sel(time='2010-01-03').mean(dim='time').plot()" 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | "execution_count": null, 525 | "metadata": { 526 | "collapsed": true 527 | }, 528 | "outputs": [], 529 | "source": [] 530 | } 531 | ], 532 | "metadata": { 533 | "kernelspec": { 534 | "display_name": "Python 3", 535 | "language": "python", 536 | "name": "python3" 537 | }, 538 | "language_info": { 539 | "codemirror_mode": { 540 | "name": "ipython", 541 | "version": 3 542 | }, 543 | "file_extension": ".py", 544 | "mimetype": "text/x-python", 545 | "name": "python", 546 | "nbconvert_exporter": "python", 547 | "pygments_lexer": "ipython3", 548 | "version": "3.5.1" 549 | } 550 | }, 551 | "nbformat": 4, 552 | "nbformat_minor": 0 553 | } 554 | -------------------------------------------------------------------------------- /OldNotebooks/XarrayAndDask_MultipleNCFiles.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "import xarray as xr\n", 13 | "import rasterio\n", 14 | "%matplotlib inline\n", 15 | "from matplotlib.pyplot import *\n", 16 | "from glob import glob\n", 17 | "import os\n", 18 | "import datetime\n", 19 | "\n", 20 | "from rasterio_to_xarray import rasterio_to_xarray, xarray_to_rasterio" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def maiac_file_to_da(filename):\n", 32 | " da = rasterio_to_xarray(filename)\n", 33 | " \n", 34 | " da.values[da.values == -28672] = np.nan\n", 35 | " da.values[da.values == 0] = np.nan\n", 36 | " \n", 37 | " #da.values = da.values.astype(np.float64)\n", 38 | " \n", 39 | " time_str = os.path.basename(filename)[17:-13]\n", 40 | " time_obj = datetime.datetime.strptime(time_str, '%Y%j%H%M')\n", 41 | " da.coords['time'] = time_obj\n", 42 | " \n", 43 | " return da" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 17, 49 | "metadata": { 50 | "collapsed": true 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "files = glob('2014_All/*_proj.tif')" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 18, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "files = files[50:]" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 19, 71 | "metadata": { 72 | "collapsed": true 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "list_of_das = map(maiac_file_to_da, files)" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 20, 82 | "metadata": { 83 | "collapsed": false 84 | }, 85 | "outputs": [ 86 | { 87 | "name": "stderr", 88 | "output_type": "stream", 89 | "text": [ 90 | "/Users/robin/code/MAIACProcessing/rasterio_to_xarray.py:29: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.\n", 91 | " data = np.where(data == src.nodata, np.nan, data)\n" 92 | ] 93 | } 94 | ], 95 | "source": [ 96 | "res = xr.concat(list_of_das, 'time')" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 21, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "r = res.resample('D', dim='time', how='max')" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 22, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "ds = r.to_dataset(name='data')" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 23, 124 | "metadata": { 125 | "collapsed": false 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "ds.to_netcdf('robin_2014_2.nc')" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "metadata": { 136 | "collapsed": false 137 | }, 138 | "outputs": [], 139 | "source": [] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 24, 144 | "metadata": { 145 | "collapsed": false 146 | }, 147 | "outputs": [], 148 | "source": [ 149 | "all_data = xr.open_mfdataset('robin_2014_*.nc', chunks={'time': 10})" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 25, 155 | "metadata": { 156 | "collapsed": true 157 | }, 158 | "outputs": [], 159 | "source": [ 160 | "all_data = all_data['data']" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 26, 166 | "metadata": { 167 | "collapsed": false 168 | }, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "((10, 10, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7),\n", 174 | " (1162,),\n", 175 | " (1240,))" 176 | ] 177 | }, 178 | "execution_count": 26, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "all_data.chunks" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 27, 190 | "metadata": { 191 | "collapsed": false 192 | }, 193 | "outputs": [ 194 | { 195 | "name": "stderr", 196 | "output_type": "stream", 197 | "text": [ 198 | "/Users/robin/anaconda3/lib/python3.5/site-packages/dask/array/numpy_compat.py:44: RuntimeWarning: invalid value encountered in true_divide\n", 199 | " x = np.divide(x1, x2, out)\n" 200 | ] 201 | } 202 | ], 203 | "source": [ 204 | "xarray_to_rasterio(all_data.mean(dim='time', keep_attrs=True), 'test_dask_overallmean3.tif')" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "metadata": { 211 | "collapsed": true 212 | }, 213 | "outputs": [], 214 | "source": [] 215 | } 216 | ], 217 | "metadata": { 218 | "_draft": { 219 | "nbviewer_url": "https://gist.github.com/18167ba0fad6420f75dc748d0e02aecb" 220 | }, 221 | "gist": { 222 | "data": { 223 | "description": "XArrayAndDask.ipynb", 224 | "public": true 225 | }, 226 | "id": "18167ba0fad6420f75dc748d0e02aecb" 227 | }, 228 | "kernelspec": { 229 | "display_name": "Python 3", 230 | "language": "python", 231 | "name": "python3" 232 | }, 233 | "language_info": { 234 | "codemirror_mode": { 235 | "name": "ipython", 236 | "version": 3 237 | }, 238 | "file_extension": ".py", 239 | "mimetype": "text/x-python", 240 | "name": "python", 241 | "nbconvert_exporter": "python", 242 | "pygments_lexer": "ipython3", 243 | "version": "3.5.1" 244 | } 245 | }, 246 | "nbformat": 4, 247 | "nbformat_minor": 0 248 | } 249 | -------------------------------------------------------------------------------- /OldNotebooks/XarrayAndDask_OneNCFile.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 49, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "import xarray as xr\n", 13 | "import rasterio\n", 14 | "%matplotlib inline\n", 15 | "from matplotlib.pyplot import *\n", 16 | "from glob import glob\n", 17 | "import os\n", 18 | "import datetime\n", 19 | "\n", 20 | "from rasterio_to_xarray import rasterio_to_xarray, xarray_to_rasterio" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 50, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def maiac_file_to_da(filename):\n", 32 | " da = rasterio_to_xarray(filename)\n", 33 | " \n", 34 | " da.values[da.values == -28672] = np.nan\n", 35 | " da.values[da.values == 0] = np.nan\n", 36 | " \n", 37 | " #da.values = da.values.astype(np.float64)\n", 38 | " \n", 39 | " time_str = os.path.basename(filename)[17:-13]\n", 40 | " time_obj = datetime.datetime.strptime(time_str, '%Y%j%H%M')\n", 41 | " da.coords['time'] = time_obj\n", 42 | " \n", 43 | " return da" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 51, 49 | "metadata": { 50 | "collapsed": true 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "files = glob('2014_All/*_proj.tif')" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 52, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "list_of_das = map(maiac_file_to_da, files)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 53, 71 | "metadata": { 72 | "collapsed": false 73 | }, 74 | "outputs": [ 75 | { 76 | "name": "stderr", 77 | "output_type": "stream", 78 | "text": [ 79 | "/Users/robin/code/MAIACProcessing/rasterio_to_xarray.py:29: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.\n", 80 | " data = np.where(data == src.nodata, np.nan, data)\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "res = xr.concat(list_of_das, 'time')" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 54, 91 | "metadata": { 92 | "collapsed": false 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "r = res.resample('D', dim='time', how='max')" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 55, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "ds = r.to_dataset(name='data')" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 57, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "ds.to_netcdf('robin_2014_All.nc')" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "collapsed": false 126 | }, 127 | "outputs": [], 128 | "source": [] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 58, 133 | "metadata": { 134 | "collapsed": false 135 | }, 136 | "outputs": [], 137 | "source": [ 138 | "all_data = xr.open_mfdataset('robin_2014_All.nc', chunks={'time': 10})" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 59, 144 | "metadata": { 145 | "collapsed": true 146 | }, 147 | "outputs": [], 148 | "source": [ 149 | "all_data = all_data['data']" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 60, 155 | "metadata": { 156 | "collapsed": false 157 | }, 158 | "outputs": [ 159 | { 160 | "data": { 161 | "text/plain": [ 162 | "((10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1),\n", 163 | " (1162,),\n", 164 | " (1240,))" 165 | ] 166 | }, 167 | "execution_count": 60, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "all_data.chunks" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 61, 179 | "metadata": { 180 | "collapsed": false 181 | }, 182 | "outputs": [ 183 | { 184 | "name": "stderr", 185 | "output_type": "stream", 186 | "text": [ 187 | "/Users/robin/anaconda3/lib/python3.5/site-packages/dask/array/numpy_compat.py:44: RuntimeWarning: invalid value encountered in true_divide\n", 188 | " x = np.divide(x1, x2, out)\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "xarray_to_rasterio(all_data.mean(dim='time', keep_attrs=True), 'test_dask_overallmean2.tif')" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": { 200 | "collapsed": true 201 | }, 202 | "outputs": [], 203 | "source": [] 204 | } 205 | ], 206 | "metadata": { 207 | "_draft": { 208 | "nbviewer_url": "https://gist.github.com/18167ba0fad6420f75dc748d0e02aecb" 209 | }, 210 | "gist": { 211 | "data": { 212 | "description": "XArrayAndDask.ipynb", 213 | "public": true 214 | }, 215 | "id": "18167ba0fad6420f75dc748d0e02aecb" 216 | }, 217 | "kernelspec": { 218 | "display_name": "Python 3", 219 | "language": "python", 220 | "name": "python3" 221 | }, 222 | "language_info": { 223 | "codemirror_mode": { 224 | "name": "ipython", 225 | "version": 3 226 | }, 227 | "file_extension": ".py", 228 | "mimetype": "text/x-python", 229 | "name": "python", 230 | "nbconvert_exporter": "python", 231 | "pygments_lexer": "ipython3", 232 | "version": "3.5.1" 233 | } 234 | }, 235 | "nbformat": 4, 236 | "nbformat_minor": 0 237 | } 238 | -------------------------------------------------------------------------------- /OldNotebooks/XarrayDtypesIssues.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import xarray as xr\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 7, 18 | "metadata": { 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "xa = xr.DataArray(data=np.random.rand(10, 10).astype(np.float32))\n", 24 | "xa.to_dataset(name='data').to_netcdf('test.nc')" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 9, 30 | "metadata": { 31 | "collapsed": true 32 | }, 33 | "outputs": [], 34 | "source": [] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 16, 39 | "metadata": { 40 | "collapsed": true 41 | }, 42 | "outputs": [], 43 | "source": [ 44 | "dask_data = xr.open_dataset('test.nc', chunks={'dim_0': 2})['data']\n", 45 | "dask_data.mean(dim='dim_0').dtype\n", 46 | " # => float32\n", 47 | "dask_data.mean(dim='dim_0').load().dtype\n", 48 | " # => float64" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 26, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [ 58 | { 59 | "data": { 60 | "text/plain": [ 61 | "dtype('float32')" 62 | ] 63 | }, 64 | "execution_count": 26, 65 | "metadata": {}, 66 | "output_type": "execute_result" 67 | } 68 | ], 69 | "source": [ 70 | "normal_data = xr.open_dataset('test.nc')['data']\n", 71 | "normal_data.dtype\n", 72 | " # => float32\n", 73 | "normal_data.mean(dim='dim_0').dtype\n", 74 | " # => float32" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": { 81 | "collapsed": true 82 | }, 83 | "outputs": [], 84 | "source": [] 85 | } 86 | ], 87 | "metadata": { 88 | "kernelspec": { 89 | "display_name": "Python 3", 90 | "language": "python", 91 | "name": "python3" 92 | }, 93 | "language_info": { 94 | "codemirror_mode": { 95 | "name": "ipython", 96 | "version": 3 97 | }, 98 | "file_extension": ".py", 99 | "mimetype": "text/x-python", 100 | "name": "python", 101 | "nbconvert_exporter": "python", 102 | "pygments_lexer": "ipython3", 103 | "version": "3.5.1" 104 | } 105 | }, 106 | "nbformat": 4, 107 | "nbformat_minor": 0 108 | } 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XArrayAndRasterio 2 | Experimental code for loading/saving XArray DataArrays to Geographic Rasters using rasterio 3 | 4 | Requirements: 5 | - `xarray` 6 | - `numpy` 7 | - `rasterio` 8 | - `pandas` 9 | 10 | Functions provided: 11 | - `xarray_to_rasterio`: Allows you to export an xarray DataArray to a rasterio-compatible file (GeoTIFF mainly) 12 | - `rasterio_to_xarray`: Allows you to read any rasterio-compatible file into an xarray DataArray 13 | - `xarray_to_rasterio_by_band`: Same as `xarray_to_rasterio` but exports one file per band 14 | 15 | Author: Robin Wilson (robin@rtwilson.com). Experimental code! 16 | -------------------------------------------------------------------------------- /rasterio_to_xarray.py: -------------------------------------------------------------------------------- 1 | import rasterio 2 | import xarray as xr 3 | import numpy as np 4 | import pandas as pd 5 | import os 6 | 7 | def rasterio_to_xarray(fname): 8 | """Converts the given file to an xarray.DataArray object. 9 | 10 | Arguments: 11 | - `fname`: the filename of the rasterio-compatible file to read 12 | 13 | Returns: 14 | An xarray.DataArray object containing the data from the given file, 15 | along with the relevant geographic metadata. 16 | 17 | Notes: 18 | This produces an xarray.DataArray object with two dimensions: x and y. 19 | The co-ordinates for these dimensions are set based on the geographic 20 | reference defined in the original file. 21 | 22 | This has only been tested with GeoTIFF files: use other types of files 23 | at your own risk!""" 24 | with rasterio.drivers(): 25 | with rasterio.open(fname) as src: 26 | data = src.read(1) 27 | 28 | # Set values to nan wherever they are equal to the nodata 29 | # value defined in the input file 30 | data = np.where(data == src.nodata, np.nan, data) 31 | 32 | # Get coords 33 | nx, ny = src.width, src.height 34 | x0, y0 = src.bounds.left, src.bounds.top 35 | dx, dy = src.res[0], -src.res[1] 36 | 37 | coords = {'y': np.arange(start=y0, stop=(y0 + ny * dy), step=dy), 38 | 'x': np.arange(start=x0, stop=(x0 + nx * dx), step=dx)} 39 | 40 | dims = ('y', 'x') 41 | 42 | attrs = {} 43 | 44 | try: 45 | aff = src.affine 46 | attrs['affine'] = aff.to_gdal() 47 | except AttributeError: 48 | pass 49 | 50 | try: 51 | c = src.crs 52 | attrs['crs'] = c.to_string() 53 | except AttributeError: 54 | pass 55 | 56 | return xr.DataArray(data, dims=dims, coords=coords, attrs=attrs) 57 | 58 | 59 | def xarray_to_rasterio(xa, output_filename): 60 | """Converts the given xarray.DataArray object to a raster output file 61 | using rasterio. 62 | 63 | Arguments: 64 | - `xa`: The xarray.DataArray to convert 65 | - `output_filename`: the filename to store the output GeoTIFF file in 66 | 67 | Notes: 68 | Converts the given xarray.DataArray to a GeoTIFF output file using rasterio. 69 | 70 | This function only supports 2D or 3D DataArrays, and GeoTIFF output. 71 | 72 | The input DataArray must have attributes (stored as xa.attrs) specifying 73 | geographic metadata, or the output will have _no_ geographic information. 74 | 75 | If the DataArray uses dask as the storage backend then this function will 76 | force a load of the raw data. 77 | """ 78 | # Forcibly compute the data, to ensure that all of the metadata is 79 | # the same as the actual data (ie. dtypes are the same etc) 80 | xa = xa.load() 81 | 82 | if len(xa.shape) == 2: 83 | count = 1 84 | height = xa.shape[0] 85 | width = xa.shape[1] 86 | band_indicies = 1 87 | else: 88 | count = xa.shape[0] 89 | height = xa.shape[1] 90 | width = xa.shape[2] 91 | band_indicies = np.arange(count) + 1 92 | 93 | processed_attrs = {} 94 | 95 | try: 96 | val = xa.attrs['affine'] 97 | processed_attrs['affine'] = rasterio.Affine.from_gdal(*val) 98 | except KeyError: 99 | pass 100 | 101 | try: 102 | val = xa.attrs['crs'] 103 | processed_attrs['crs'] = rasterio.crs.CRS.from_string(val) 104 | except KeyError: 105 | pass 106 | 107 | with rasterio.open(output_filename, 'w', 108 | driver='GTiff', 109 | height=height, width=width, 110 | dtype=str(xa.dtype), count=count, 111 | **processed_attrs) as dst: 112 | dst.write(xa.values, band_indicies) 113 | 114 | 115 | def xarray_to_rasterio_by_band(xa, output_basename, dim='time', date_format='%Y-%m-%d'): 116 | for i in range(len(xa[dim])): 117 | args = {dim: i} 118 | data = xa.isel(**args) 119 | index_value = data[dim].values 120 | 121 | if type(index_value) is np.datetime64: 122 | formatted_index = pd.to_datetime(index_value).strftime(date_format) 123 | else: 124 | formatted_index = str(index_value) 125 | 126 | filename = output_basename + formatted_index + '.tif' 127 | xarray_to_rasterio(data, filename) 128 | print('Exported %s' % formatted_index) 129 | --------------------------------------------------------------------------------