├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── example.png ├── examples ├── cca │ ├── cca.r │ ├── cca_example.png │ └── example_output.txt ├── example_eval.py ├── example_points.py └── example_raster_sampling.py ├── img ├── example_certainty.png ├── example_responses.png ├── memory.png └── time.png ├── release.sh ├── requirements.txt ├── setup.cfg ├── setup.py ├── src └── pyimpute │ ├── __init__.py │ └── _main.py └── tests ├── __init__.py ├── conftest.py ├── data ├── dtmean8_12.img ├── gt_dem.img ├── int_cnl_euc.img ├── p_n.img ├── pmean_all.img ├── points.geojson ├── responses.tif ├── tmax8.img └── tmean_all.img └── test_impute.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | out1/* 3 | out2/* 4 | *.prof 5 | examples/_* 6 | *.egg-info 7 | dist/* 8 | build/* 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | python: 4 | - "3.6" 5 | - "3.8" 6 | before_install: 7 | - pip install -U pip 8 | install: 9 | - pip install pytest 10 | - pip install -e . 11 | script: "py.test" 12 | after_success: 13 | - coveralls 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Matthew Perry 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of the software nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.txt README.md 2 | exclude MANIFEST.in 3 | exclude Vagrantfile 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![travis](https://travis-ci.org/perrygeo/pyimpute.svg) 2 | 3 | ## Python module for geospatial prediction using scikit-learn and rasterio 4 | 5 | `pyimpute` provides high-level python functions for bridging the gap between spatial data formats and machine learning software to facilitate supervised classification and regression on geospatial data. This allows you to create landscape-scale predictions based on sparse observations. 6 | 7 | The observations, known as the **training data**, consists of: 8 | 9 | * response variables: what we are trying to predict 10 | * explanatory variables: variables which explain the spatial patterns of responses 11 | 12 | The **target data** consists of explanatory variables represented by raster datasets. There are no response variables available for the target data; the goal is to *predict* a raster surface of responses. The responses can either be discrete (classification) or continuous (regression). 13 | 14 | ![example](https://raw.githubusercontent.com/perrygeo/pyimpute/master/example.png) 15 | 16 | ## Pyimpute Functions 17 | 18 | * `load_training_vector`: Load training data where responses are vector data (explanatory variables are always raster) 19 | * `load_training_raster`: Load training data where responses are raster data 20 | * `stratified_sample_raster`: Random sampling of raster cells based on discrete classes 21 | * `evaluate_clf`: Performs cross-validation and prints metrics to help tune your scikit-learn classifiers. 22 | * `load_targets`: Loads target raster data into data structures required by scikit-learn 23 | * `impute`: takes target data and your scikit-learn classifier and makes predictions, outputing GeoTiffs 24 | 25 | These functions don't really provide any ground-breaking new functionality, they merely saves lots of tedious data wrangling that would otherwise bog your analysis down in low-level details. In other words, `pyimpute` provides a high-level python workflow for spatial prediction, making it easier to: 26 | 27 | * explore new variables more easily 28 | * frequently update predictions with new information (e.g. new Landsat imagery as it becomes available) 29 | * bring the technique to other disciplines and geographies 30 | 31 | 32 | ### Basic example 33 | 34 | Here's what a `pyimpute` workflow might look like. In this example, we have two explanatory variables as rasters (temperature and precipitation) and a geojson with point observations of habitat suitability for a plant species. Our goal is to predict habitat suitability across the entire region based only on the explanatory variables. 35 | 36 | ``` 37 | from pyimpute import load_training_vector, load_targets, impute, evaluate_clf 38 | from sklearn.ensemble import RandomForestClassifier 39 | ``` 40 | 41 | Load some training data 42 | ``` 43 | explanatory_rasters = ['temperature.tif', 'precipitation.tif'] 44 | response_data = 'point_observations.geojson' 45 | 46 | train_xs, train_y = load_training_vector(response_data, 47 | explanatory_rasters, 48 | response_field="suitability") 49 | ``` 50 | 51 | Train a scikit-learn classifier 52 | ``` 53 | clf = RandomForestClassifier(n_estimators=10, n_jobs=1) 54 | clf.fit(train_xs, train_y) 55 | ``` 56 | 57 | Evalute the classifier using several validation metrics, manually inspecting the output 58 | ``` 59 | evaluate_clf(clf, train_xs, train_y) 60 | ``` 61 | 62 | Load target raster data 63 | ``` 64 | target_xs, raster_info = load_targets(explanatory_rasters) 65 | ``` 66 | 67 | Make predictions, outputing geotiffs 68 | ``` 69 | impute(target_xs, clf, raster_info, outdir='/tmp', 70 | linechunk=400, class_prob=True, certainty=True) 71 | 72 | assert os.path.exists("/tmp/responses.tif") 73 | assert os.path.exists("/tmp/certainty.tif") 74 | assert os.path.exists("/tmp/probability_0.tif") 75 | assert os.path.exists("/tmp/probability_1.tif") 76 | ``` 77 | 78 | ### Installation 79 | 80 | Assuming you have `libgdal` and the scipy system dependencies installed, you can install with pip 81 | 82 | ``` 83 | pip install pyimpute 84 | ``` 85 | 86 | Alternatively, install from the source code 87 | ``` 88 | git clone https://github.com/perrygeo/pyimpute.git 89 | cd pyimpute 90 | pip install -e . 91 | ``` 92 | 93 | See the `.travis.yml` file for a working example on Ubuntu systems. 94 | 95 | ### Other resources 96 | 97 | For an overview, watch my presentation at FOSS4G 2014: Spatial-Temporal Prediction of Climate Change Impacts using pyimpute, scikit-learn and GDAL — Matthew Perry 98 | 99 | Also, check out [the examples](https://github.com/perrygeo/python-impute/blob/master/examples/) and [the wiki](https://github.com/perrygeo/pyimpute/wiki) 100 | -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/example.png -------------------------------------------------------------------------------- /examples/cca/cca.r: -------------------------------------------------------------------------------- 1 | library(vegan) 2 | library(labdsv) 3 | 4 | data(varespec) 5 | data(varechem) 6 | 7 | vare.cca <- cca(varespec ~ Baresoil+Humdepth+pH+N+P+K+Ca+Mg+S+Al+Fe, data=varechem) 8 | vare.cca 9 | plot(vare.cca) 10 | summary(vare.cca) 11 | 12 | // See also http://ecology.msu.montana.edu/labdsv/R/labs/lab12/lab12.html -------------------------------------------------------------------------------- /examples/cca/cca_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/examples/cca/cca_example.png -------------------------------------------------------------------------------- /examples/cca/example_output.txt: -------------------------------------------------------------------------------- 1 | > vare.cca 2 | Call: cca(formula = varespec ~ Baresoil + Humdepth + pH + N + P + K + Ca + Mg + S + Al + Fe, data = varechem) 3 | 4 | Inertia Proportion Rank 5 | Total 2.0832 1.0000 6 | Constrained 1.2154 0.5834 11 7 | Unconstrained 0.8678 0.4166 12 8 | Inertia is mean squared contingency coefficient 9 | 10 | Eigenvalues for constrained axes: 11 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 CCA7 CCA8 CCA9 CCA10 CCA11 12 | 0.410865 0.255619 0.146158 0.131515 0.091575 0.078525 0.060261 0.019134 0.008944 0.006849 0.005946 13 | 14 | Eigenvalues for unconstrained axes: 15 | CA1 CA2 CA3 CA4 CA5 CA6 CA7 CA8 CA9 CA10 CA11 CA12 16 | 0.253513 0.151934 0.126683 0.093370 0.075393 0.049632 0.037929 0.026435 0.021758 0.014304 0.009052 0.007806 17 | 18 | 19 | > plot(vare.cca) 20 | > summary(vare.cca) 21 | 22 | Call: 23 | cca(formula = varespec ~ Baresoil + Humdepth + pH + N + P + K + Ca + Mg + S + Al + Fe, data = varechem) 24 | 25 | Partitioning of mean squared contingency coefficient: 26 | Inertia Proportion 27 | Total 2.0832 1.0000 28 | Constrained 1.2154 0.5834 29 | Unconstrained 0.8678 0.4166 30 | 31 | Eigenvalues, and their contribution to the mean squared contingency coefficient 32 | 33 | Importance of components: 34 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 CCA7 CCA8 35 | Eigenvalue 0.4109 0.2556 0.14616 0.13152 0.09158 0.07852 0.06026 0.01913 36 | Proportion Explained 0.1972 0.1227 0.07016 0.06313 0.04396 0.03769 0.02893 0.00918 37 | Cumulative Proportion 0.1972 0.3199 0.39009 0.45322 0.49718 0.53488 0.56381 0.57299 38 | CCA9 CCA10 CCA11 CA1 CA2 CA3 CA4 CA5 39 | Eigenvalue 0.008944 0.006849 0.005946 0.2535 0.15193 0.12668 0.09337 0.07539 40 | Proportion Explained 0.004290 0.003290 0.002850 0.1217 0.07293 0.06081 0.04482 0.03619 41 | Cumulative Proportion 0.577280 0.580570 0.583430 0.7051 0.77805 0.83886 0.88368 0.91988 42 | CA6 CA7 CA8 CA9 CA10 CA11 CA12 43 | Eigenvalue 0.04963 0.03793 0.02643 0.02176 0.01430 0.009052 0.007806 44 | Proportion Explained 0.02382 0.01821 0.01269 0.01044 0.00687 0.004350 0.003750 45 | Cumulative Proportion 0.94370 0.96191 0.97460 0.98504 0.99191 0.996250 1.000000 46 | 47 | Accumulated constrained eigenvalues 48 | Importance of components: 49 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 CCA7 CCA8 50 | Eigenvalue 0.4109 0.2556 0.1462 0.1315 0.09158 0.07852 0.06026 0.01913 51 | Proportion Explained 0.3381 0.2103 0.1203 0.1082 0.07535 0.06461 0.04958 0.01574 52 | Cumulative Proportion 0.3381 0.5484 0.6686 0.7768 0.85218 0.91679 0.96637 0.98211 53 | CCA9 CCA10 CCA11 54 | Eigenvalue 0.008944 0.006849 0.005946 55 | Proportion Explained 0.007360 0.005630 0.004890 56 | Cumulative Proportion 0.989470 0.995110 1.000000 57 | 58 | Scaling 2 for species and site scores 59 | * Species are scaled proportional to eigenvalues 60 | * Sites are unscaled: weighted dispersion equal on all dimensions 61 | 62 | 63 | Species scores 64 | 65 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 66 | Cal.vul 0.2579826 -0.80872 1.94560 -0.35626 0.697113 -0.74258 67 | Emp.nig -0.2704679 -0.05299 -0.14437 -0.32584 -0.170125 -0.04192 68 | Led.pal -0.9762750 -0.37214 -0.06644 -0.75402 -0.697058 0.06306 69 | Vac.myr -1.3055169 -0.11479 0.17137 0.27104 -0.599337 0.07048 70 | Vac.vit -0.1929037 0.08757 -0.21288 -0.35303 -0.066669 -0.10932 71 | Pin.syl 0.2380445 0.22966 0.05686 -0.39593 -0.019382 0.07840 72 | Des.fle -1.4062903 0.38398 0.39272 0.39030 -0.101391 0.30965 73 | Bet.pub -0.5960443 -0.95617 -0.72698 -1.67618 -1.588060 -0.32047 74 | Vac.uli 0.3926825 -0.94198 -0.39399 0.58151 -0.228095 -0.14642 75 | Dip.mon 0.0229110 -0.49673 -0.89897 -0.40174 -0.174258 -0.26730 76 | Dic.sp -0.4868957 0.65851 -1.26929 0.02094 1.419951 -0.57922 77 | Dic.fus -0.4861256 -0.47490 0.52892 -0.51872 0.229919 0.59969 78 | Dic.pol -0.3223530 -0.20367 -1.05718 -0.83490 -0.119395 -0.73626 79 | Hyl.spl -1.8827323 0.65465 0.49959 1.53295 -0.308169 0.16247 80 | Ple.sch -0.9252145 0.28944 0.09530 0.27152 0.053829 -0.02879 81 | Pol.pil 0.2594323 -0.52462 -0.49858 0.08717 0.163650 0.43618 82 | Pol.jun -0.7366157 0.12464 -0.27517 -0.14649 -0.314192 0.31794 83 | Pol.com -0.9458638 -0.14755 -0.27373 -0.71188 -0.855045 -0.28475 84 | Poh.nut -0.0348872 0.21735 -0.33522 -0.36923 0.179971 -0.30020 85 | Pti.cil -0.5533110 -0.80045 -0.73937 -1.41351 -1.316239 -0.52927 86 | Bar.lyc -0.5655746 -1.05360 -0.79808 -1.74760 -1.740288 -0.58626 87 | Cla.arb 0.3082534 -0.56549 -0.03583 0.08219 -0.096060 -0.13535 88 | Cla.ran 0.4695611 -0.53152 -0.16623 0.29331 0.037571 0.13895 89 | Cla.ste 0.7627157 0.70289 0.12199 -0.02713 -0.053315 0.10624 90 | Cla.unc -0.0840257 -0.04106 -0.16775 -0.54249 0.443329 -0.24384 91 | Cla.coc 0.1998745 -0.11892 0.05746 -0.11248 0.073434 0.09607 92 | Cla.cor -0.3377207 0.00630 -0.30418 -0.13082 0.007785 -0.09738 93 | Cla.gra -0.0591848 -0.14946 -0.27214 -0.18229 0.113776 -0.19158 94 | Cla.fim -0.0005966 -0.11638 0.03219 -0.27266 -0.185276 0.01141 95 | Cla.cri -0.2353142 -0.13014 0.04825 -0.44966 -0.082457 -0.30900 96 | Cla.chl 0.2960198 0.43031 -0.44880 -0.45712 -0.026098 -0.32614 97 | Cla.bot -0.6121890 -0.67705 -0.17531 -1.05814 -0.701290 -0.74162 98 | Cla.ama 0.0339234 -0.89659 -1.10581 -0.06753 0.078437 0.24184 99 | Cla.sp 0.6893702 0.73032 0.49452 -0.39382 0.126202 -0.21620 100 | Cet.eri 0.2703176 0.10341 -0.30842 -0.06482 0.593267 -0.44989 101 | Cet.isl 0.1448207 0.10344 -0.31552 -0.70305 -0.482515 -0.22317 102 | Cet.niv 1.3069886 -0.01489 0.54845 1.61791 -1.099398 -2.15267 103 | Nep.arc -0.8040582 0.39185 -0.06934 -0.02375 -0.746439 1.04971 104 | Ste.sp 0.2935602 -1.44392 -0.78477 0.79952 0.694834 0.72962 105 | Pel.aph -0.6296777 0.05166 -0.34405 -0.15437 -0.058790 -0.21384 106 | Ich.eri 0.3228067 -1.83898 -0.44899 0.64843 0.595119 0.78301 107 | Cla.cer 0.9088477 0.22411 0.50813 1.00260 -0.582433 -0.84668 108 | Cla.def -0.3460925 -0.21145 -0.11090 -0.54258 0.007175 -0.33724 109 | Cla.phy 0.7223026 1.12784 -0.05001 -0.23188 0.099363 0.06092 110 | 111 | 112 | Site scores (weighted averages of species scores) 113 | 114 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 115 | 18 0.2368 -1.0455 -0.79083 -0.149031 -0.49251 -0.35212 116 | 15 -0.9799 -0.2750 0.34407 0.111139 0.63356 0.30849 117 | 24 -1.0983 0.8478 -2.51016 -0.080535 4.40120 -2.69293 118 | 27 -1.6399 0.4846 0.31083 1.033926 -0.68668 0.16045 119 | 23 -0.6573 -0.3813 -0.70171 -0.837942 -0.50965 -0.35934 120 | 19 -0.2220 0.6886 -0.03737 -0.002568 -0.65742 0.07187 121 | 22 -1.1371 -0.7562 1.68441 -1.251373 0.68408 1.82825 122 | 16 -0.7322 -0.9683 1.38438 -0.848066 1.09474 1.52365 123 | 28 -2.4224 0.8605 0.77192 2.459293 -1.07010 0.02053 124 | 13 0.5930 -1.4057 2.91790 -0.312366 1.59649 -2.08999 125 | 14 -0.3296 -0.8773 0.53603 -1.974878 1.81909 -0.90880 126 | 20 -0.5440 -0.3236 -0.58922 -0.198890 0.30072 -0.50529 127 | 25 -1.2792 0.4454 -1.17274 -0.360068 1.82086 0.33613 128 | 7 0.7264 -1.9319 -0.98918 1.155440 -0.49232 -0.08616 129 | 5 0.9323 -2.3201 -1.39730 2.072908 0.83123 1.69279 130 | 6 0.7454 -1.2134 -0.56548 0.372969 -0.26442 -0.15445 131 | 3 1.3118 0.5893 -0.06894 0.401225 -0.39972 0.94502 132 | 4 1.3726 -0.1616 0.83676 1.878597 -1.28329 -3.05924 133 | 2 1.3068 1.3075 0.11566 -0.055773 -0.47463 1.05104 134 | 9 1.1513 1.9030 0.25604 -0.576516 -0.64079 0.50208 135 | 12 0.9003 1.2149 0.03147 -0.437409 -0.44022 0.54418 136 | 10 1.2566 1.7341 0.25151 -0.507033 -0.60207 0.74947 137 | 11 0.4809 0.1232 -0.01664 0.339108 0.09187 0.24062 138 | 21 -0.8258 -0.3306 -1.27405 -2.712570 -3.96294 -1.33584 139 | 140 | 141 | Site constraints (linear combinations of constraining variables) 142 | 143 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 144 | 18 -0.51001 -0.86277 -1.265868 -0.84832 0.00585 -0.55362 145 | 15 -0.11359 0.47962 0.292164 -0.71983 -1.13275 -0.12336 146 | 24 -0.22365 0.90898 -2.201280 0.15538 2.96165 -1.67268 147 | 27 -1.64472 0.76232 0.420020 0.74263 -0.06008 0.22434 148 | 23 -1.32539 -0.30282 -0.919558 -0.37197 0.23629 -0.78394 149 | 19 -1.07981 0.11303 -0.113499 -0.60422 -0.19793 -1.29585 150 | 22 -0.80792 -0.42650 1.084574 -0.98064 1.21790 1.50140 151 | 16 -0.09523 -1.62392 0.407793 -0.06884 -0.07282 0.33619 152 | 28 -2.23615 0.64537 0.663728 2.48585 -0.46791 0.25333 153 | 13 0.42015 -1.10098 3.235920 -0.54956 1.29688 -1.38806 154 | 14 -0.14558 -0.43109 0.310536 -0.84389 0.19863 -0.03026 155 | 20 -0.46785 0.19132 -0.309976 -1.55804 -0.35312 -0.83013 156 | 25 -0.94343 0.48338 -0.020181 -0.08962 -0.75201 1.14075 157 | 7 1.13410 -1.71592 -0.683778 1.28206 -0.45511 -0.70628 158 | 5 0.46572 -2.30802 -1.130203 1.25890 1.45704 1.70523 159 | 6 0.86525 0.07408 -0.448437 -0.03867 -0.80286 1.09713 160 | 3 1.05262 0.42467 -0.654573 0.68815 -1.10660 0.89967 161 | 4 1.39514 -0.07478 0.728546 1.89627 -1.33345 -2.59477 162 | 2 1.33321 0.54940 0.492977 0.24130 0.78232 0.74187 163 | 9 1.29092 1.95150 0.005342 -0.81565 0.26355 0.18074 164 | 12 0.41778 0.20237 0.558481 -0.57975 -0.17713 0.78064 165 | 10 0.48239 1.37874 -0.125838 0.29170 0.38215 -0.13758 166 | 11 0.56717 0.36508 -0.101642 -0.04929 -0.36747 0.15785 167 | 21 -0.55130 -1.11370 -0.928444 -1.85875 -1.87942 -0.58312 168 | 169 | 170 | Biplot scores for constraining variables 171 | 172 | CCA1 CCA2 CCA3 CCA4 CCA5 CCA6 173 | Baresoil -0.52916 -0.39394 -0.08617 -0.48990 -0.17135 -0.47822 174 | Humdepth -0.74502 0.09330 0.17115 -0.23030 -0.12889 -0.16495 175 | pH 0.50738 0.14614 -0.26885 0.17600 -0.10593 0.17747 176 | N -0.18023 -0.58693 0.04837 0.36820 0.15022 0.16997 177 | P -0.36138 0.63661 0.04617 0.32849 0.17792 -0.38565 178 | K -0.39232 0.31726 0.55953 0.12491 0.25046 -0.48506 179 | Ca -0.48559 0.41273 0.01284 -0.06856 0.28471 -0.24271 180 | Mg -0.45563 0.35145 -0.07675 -0.07944 0.47484 -0.50687 181 | S -0.03901 0.50851 0.36649 0.02615 0.41656 -0.63216 182 | Al 0.80742 0.10327 0.25002 0.22841 -0.03898 -0.35763 183 | Fe 0.67570 0.02563 0.09560 0.24078 -0.08059 -0.04175 184 | -------------------------------------------------------------------------------- /examples/example_eval.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import os 4 | from pyimpute import load_training_vector, evaluate_clf 5 | from sklearn.ensemble import ExtraTreesClassifier 6 | import json 7 | import numpy as np 8 | 9 | import logging 10 | logger = logging.getLogger('pyimpute') 11 | logger.setLevel(logging.DEBUG) 12 | sh = logging.StreamHandler(stream=sys.stdout) 13 | logger.addHandler(sh) 14 | 15 | 16 | TRAINING_DIR = "./_usfs_data" 17 | 18 | 19 | def main(): 20 | 21 | # Define the known data points or "training" data 22 | explanatory_fields = "d100 dd0 dd5 fday ffp gsdd5 gsp map mat_tenths mmax_tenths mmindd0 mmin_tenths mtcm_tenths mtwm_tenths sday".split() 23 | explanatory_rasters = [os.path.join(TRAINING_DIR, "current_" + r + ".img") for r in explanatory_fields] 24 | response_shapes = os.path.join(TRAINING_DIR, "DF.shp") 25 | 26 | # Load the training rasters using the sampled subset 27 | try: 28 | cached = json.load(open("_cached_training.json")) 29 | train_xs = np.array(cached['train_xs']) 30 | train_y = np.array(cached['train_y']) 31 | except IOError: 32 | train_xs, train_y = load_training_vector(response_shapes, 33 | explanatory_rasters, response_field='GRIDCODE') 34 | cache = {'train_xs': train_xs.tolist(), 'train_y': train_y.tolist()} 35 | with open("_cached_training.json", 'w') as fh: 36 | fh.write(json.dumps(cache)) 37 | 38 | print(train_xs.shape, train_y.shape) 39 | 40 | # Train the classifier 41 | clf = ExtraTreesClassifier(n_estimators=120, n_jobs=3) 42 | clf.fit(train_xs, train_y) 43 | print(clf) 44 | 45 | evaluate_clf(clf, train_xs, train_y, feature_names=explanatory_fields) 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /examples/example_points.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import os 4 | from pyimpute import load_training_vector, load_targets, impute 5 | from sklearn.ensemble import ExtraTreesClassifier 6 | from sklearn import cross_validation 7 | import json 8 | import numpy as np 9 | 10 | import logging 11 | logger = logging.getLogger('pyimpute') 12 | logger.setLevel(logging.DEBUG) 13 | sh = logging.StreamHandler(stream=sys.stdout) 14 | logger.addHandler(sh) 15 | 16 | 17 | TRAINING_DIR = "./_usfs_data" 18 | 19 | 20 | def main(): 21 | 22 | # Define the known data points or "training" data 23 | explanatory_fields = "d100 dd0 dd5 fday ffp gsdd5 gsp map mat_tenths mmax_tenths mmindd0 mmin_tenths mtcm_tenths mtwm_tenths sday".split() 24 | explanatory_rasters = [os.path.join(TRAINING_DIR, "current_" + r + ".img") for r in explanatory_fields] 25 | response_shapes = os.path.join(TRAINING_DIR, "DF.shp") 26 | 27 | # Load the training rasters using the sampled subset 28 | try: 29 | cached = json.load(open("_cached_training.json")) 30 | train_xs = np.array(cached['train_xs']) 31 | train_y = np.array(cached['train_y']) 32 | except IOError: 33 | train_xs, train_y = load_training_vector(response_shapes, 34 | explanatory_rasters, response_field='GRIDCODE') 35 | cache = {'train_xs': train_xs.tolist(), 'train_y': train_y.tolist()} 36 | with open("_cached_training.json", 'w') as fh: 37 | fh.write(json.dumps(cache)) 38 | 39 | print(train_xs.shape, train_y.shape) 40 | 41 | # Train the classifier 42 | clf = ExtraTreesClassifier(n_estimators=120, n_jobs=3) 43 | clf.fit(train_xs, train_y) 44 | print(clf) 45 | 46 | # Cross validate 47 | k = 5 48 | scores = cross_validation.cross_val_score(clf, train_xs, train_y, cv=k) 49 | print("%d-fold Cross Validation Accuracy: %0.2f (+/- %0.2f)" % (k, scores.mean() * 100, scores.std() * 200)) 50 | 51 | # Run the model on the current data; i.e. predict current conditions 52 | print("Imputing response rasters FOR CURRENT DATA") 53 | target_xs, raster_info = load_targets(explanatory_rasters) 54 | 55 | impute(target_xs, clf, raster_info, outdir="_usfs_output_current", 56 | linechunk=400, class_prob=True, certainty=True) 57 | 58 | years = ['2060'] 59 | for year in years: 60 | print("Loading target explanatory raster data, swapping out for %s climate data" % year) 61 | 62 | # Swap out for future climate rasters 63 | new_explanatory_rasters = [os.path.join(TRAINING_DIR, "Ensemble_rcp60_y%s_%s.img" % (year, r)) 64 | for r in explanatory_fields] 65 | 66 | target_xs, raster_info = load_targets(new_explanatory_rasters) 67 | 68 | print("Imputing response rasters") 69 | impute(target_xs, clf, raster_info, outdir="_usfs_output_%s" % year, 70 | linechunk=400, class_prob=True, certainty=True) 71 | 72 | if __name__ == '__main__': 73 | main() 74 | -------------------------------------------------------------------------------- /examples/example_raster_sampling.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import os 4 | from pyimpute import load_training_rasters, load_targets, impute 5 | from pyimpute import stratified_sample_raster 6 | from sklearn.ensemble import ExtraTreesClassifier 7 | from sklearn import cross_validation 8 | from collections import OrderedDict 9 | 10 | import logging 11 | logger = logging.getLogger('pyimpute') 12 | logger.setLevel(logging.DEBUG) 13 | sh = logging.StreamHandler(stream=sys.stdout) 14 | logger.addHandler(sh) 15 | 16 | 17 | TRAINING_DIR = "./_aez_data/training" 18 | 19 | 20 | def main(): 21 | # Define the known data points or "training" data 22 | explanatory_fields = "tmin12c tmax8c p_ph_c pmean_wntrc pmean_sumrc irr_lands gt_demc grwsnc d2u2c".split() 23 | explanatory_rasters = [os.path.join(TRAINING_DIR, r, "hdr.adf") for r in explanatory_fields] 24 | response_raster = os.path.join(TRAINING_DIR, 'iso_zns3-27/hdr.adf') 25 | 26 | # Take a random stratified sample 27 | selected = stratified_sample_raster(response_raster, 28 | target_sample_size=20, min_sample_proportion=0.01) 29 | 30 | # Load the training rasters using the sampled subset 31 | train_xs, train_y = load_training_rasters(response_raster, 32 | explanatory_rasters, selected) 33 | print(train_xs.shape, train_y.shape) 34 | 35 | # Train the classifier 36 | clf = ExtraTreesClassifier(n_estimators=10, n_jobs=1) 37 | clf.fit(train_xs, train_y) 38 | print(clf) 39 | 40 | # Cross validate 41 | k = 5 42 | scores = cross_validation.cross_val_score(clf, train_xs, train_y, cv=k) 43 | print("%d-fold Cross Validation Accuracy: %0.2f (+/- %0.2f)" % (k, scores.mean() * 100, scores.std() * 200)) 44 | 45 | # ... Other model assessment 46 | 47 | # Run the model on the current data; i.e. predict itself 48 | print("Imputing response rasters FOR CURRENT DATA") 49 | target_xs, raster_info = load_targets(explanatory_rasters) 50 | 51 | impute(target_xs, clf, raster_info, outdir="_aez_output_current", 52 | linechunk=400, class_prob=True, certainty=True) 53 | 54 | sys.exit() 55 | 56 | years = ['2070s'] 57 | for year in years: 58 | print("Loading target explanatory raster data, swapping out for %s climate data" % year) 59 | 60 | fdir = os.path.join(TRAINING_DIR, "../RCP85/%s/" % year) 61 | 62 | # swap out datasets that are predicted to change over time (i.e the climate data only) 63 | climate_rasters = "grwsnc pmean_sumrc pmean_wntrc tmax8c tmin12c".split() 64 | new_explanatory_rasters = OrderedDict(zip(explanatory_fields, explanatory_rasters)) 65 | for cr in climate_rasters: 66 | new_explanatory_rasters[cr] = fdir + cr + "/hdr.adf" 67 | 68 | target_xs, raster_info = load_targets(new_explanatory_rasters.values()) 69 | 70 | print("Imputing response rasters") 71 | impute(target_xs, clf, raster_info, outdir="_aez_output_%s" % year, 72 | linechunk=40, class_prob=True, certainty=True) 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /img/example_certainty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/img/example_certainty.png -------------------------------------------------------------------------------- /img/example_responses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/img/example_responses.png -------------------------------------------------------------------------------- /img/memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/img/memory.png -------------------------------------------------------------------------------- /img/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/img/time.png -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | python setup.py sdist --formats=gztar,zip upload 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | scikit-learn 2 | scipy 3 | rasterio 4 | rasterstats>=0.9 5 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [tool:pytest] 2 | norecursedirs = examples* src* scripts* docs* 3 | # addopts = --maxfail=1 --pdb -rf -v 4 | 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from setuptools import setup 4 | from setuptools.command.test import test as TestCommand 5 | 6 | 7 | def read(fname): 8 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 9 | 10 | 11 | class PyTest(TestCommand): 12 | def finalize_options(self): 13 | TestCommand.finalize_options(self) 14 | self.test_args = [] 15 | self.test_suite = True 16 | 17 | def run_tests(self): 18 | import pytest 19 | 20 | errno = pytest.main(self.test_args) 21 | sys.exit(errno) 22 | 23 | 24 | setup( 25 | name="pyimpute", 26 | version="0.3", 27 | author="Matthew Perry", 28 | author_email="perrygeo@gmail.com", 29 | description=("Utilities for applying scikit-learn to spatial datasets"), 30 | license="BSD", 31 | keywords="gis geospatial geographic raster vector zonal statistics machinelearning", 32 | url="https://github.com/perrygeo/pyimpute", 33 | package_dir={"": "src"}, 34 | packages=["pyimpute"], 35 | long_description="See documentation at https://github.com/perrygeo/pyimpute", 36 | install_requires=["scikit-learn", "scipy", "numpy", "rasterstats", "rasterio"], 37 | tests_require=["pytest", "pyshp>=1.1.4", "coverage"], 38 | cmdclass={"test": PyTest}, 39 | classifiers=[ 40 | "Development Status :: 3 - Alpha", 41 | "Topic :: Utilities", 42 | "License :: OSI Approved :: BSD License", 43 | "Intended Audience :: Developers", 44 | "Intended Audience :: Science/Research", 45 | "Operating System :: OS Independent", 46 | "Programming Language :: Python :: 3", 47 | "Topic :: Scientific/Engineering :: GIS", 48 | ], 49 | ) 50 | -------------------------------------------------------------------------------- /src/pyimpute/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from ._main import ( 4 | load_training_vector, 5 | load_training_rasters, 6 | load_targets, 7 | impute, 8 | stratified_sample_raster, 9 | evaluate_clf, 10 | ) 11 | -------------------------------------------------------------------------------- /src/pyimpute/_main.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import rasterio 3 | import numpy as np 4 | import os 5 | import math 6 | import logging 7 | from sklearn import metrics 8 | from sklearn import model_selection 9 | 10 | logger = logging.getLogger("pyimpute") 11 | 12 | 13 | def load_training_vector( 14 | response_shapes, explanatory_rasters, response_field, metric="mean" 15 | ): 16 | """ 17 | Parameters 18 | ---------- 19 | response_shapes : Source of vector features for raster_stats; 20 | can be OGR file path or iterable of geojson-like features 21 | response_field : Field name containing the known response category (must be numeric) 22 | explanatory_rasters : List of Paths to GDAL rasters containing explanatory variables 23 | metric : Statistic to aggregate explanatory data across line and polygon vector features 24 | Defaults to 'mean' (optional) 25 | 26 | Returns 27 | ------- 28 | train_xs : Array of explanatory variables 29 | train_y : 1xN array of known responses 30 | """ 31 | from rasterstats import zonal_stats 32 | 33 | all_means = [] 34 | all_zones = None 35 | 36 | for i, raster in enumerate(explanatory_rasters): 37 | logger.debug("Rasters stats on %s" % raster) 38 | 39 | stats = zonal_stats( 40 | response_shapes, raster, stats=metric, prefix="pyimpute_", geojson_out=True 41 | ) 42 | 43 | zones = [x["properties"][response_field] for x in stats] 44 | if all_zones: 45 | assert zones == all_zones 46 | else: 47 | all_zones = zones 48 | 49 | means = [x["properties"]["pyimpute_" + metric] for x in stats] 50 | all_means.append(means) 51 | 52 | train_y = np.array(all_zones) 53 | train_xs = np.array(all_means).T 54 | 55 | return train_xs, train_y 56 | 57 | 58 | def load_training_rasters(response_raster, explanatory_rasters, selected=None): 59 | """ 60 | Parameters 61 | ---------- 62 | response_raster : Path to GDAL raster containing responses 63 | explanatory_rasters : List of Paths to GDAL rasters containing explanatory variables 64 | 65 | Returns 66 | ------- 67 | train_xs : Array of explanatory variables 68 | train_ys : 1xN array of known responses 69 | """ 70 | 71 | with rasterio.open(response_raster) as src: 72 | response_data = src.read().flatten() 73 | 74 | if selected is None: 75 | train_y = response_data 76 | else: 77 | train_y = response_data[selected] 78 | 79 | selected_data = [] 80 | for rast in explanatory_rasters: 81 | with rasterio.open(rast) as src: 82 | explanatory_data = src.read().flatten() 83 | assert explanatory_data.size == response_data.size 84 | if selected is None: 85 | selected_data.append(explanatory_data) 86 | else: 87 | selected_data.append(explanatory_data[selected]) 88 | 89 | train_xs = np.asarray(selected_data).T 90 | return train_xs, train_y 91 | 92 | 93 | def load_targets(explanatory_rasters): 94 | """ 95 | Parameters 96 | ---------- 97 | explanatory_rasters : List of Paths to GDAL rasters containing explanatory variables 98 | 99 | Returns 100 | ------- 101 | expl : Array of explanatory variables 102 | raster_info : dict of raster info 103 | """ 104 | 105 | explanatory_raster_arrays = [] 106 | transform = None 107 | shape = None 108 | crs = None 109 | 110 | for raster in explanatory_rasters: 111 | logger.debug(raster) 112 | with rasterio.open(raster) as src: 113 | ar = src.read(1) # TODO band num? 114 | 115 | # Save or check the geotransform 116 | if not transform: 117 | transform = src.transform 118 | else: 119 | assert transform.almost_equals(src.transform) 120 | 121 | # Save or check the shape 122 | if not shape: 123 | shape = ar.shape 124 | else: 125 | assert shape == ar.shape 126 | 127 | # Save or check the geotransform 128 | if not crs: 129 | crs = src.crs 130 | else: 131 | assert crs == src.crs 132 | 133 | # Flatten in one dimension 134 | arf = ar.flatten() 135 | explanatory_raster_arrays.append(arf) 136 | 137 | expl = np.array(explanatory_raster_arrays).T 138 | 139 | raster_info = { 140 | "transform": transform, 141 | "shape": shape, 142 | "crs": crs, 143 | } 144 | return expl, raster_info 145 | 146 | 147 | def impute( 148 | target_xs, 149 | clf, 150 | raster_info, 151 | outdir="output", 152 | linechunk=1000, 153 | class_prob=True, 154 | certainty=True, 155 | ): 156 | """ 157 | Parameters 158 | ---------- 159 | target_xs: Array of explanatory variables for which to predict responses 160 | clf: instance of a scikit-learn Classifier 161 | raster_info: dictionary of raster attributes with key 'gt', 'shape' and 'srs' 162 | 163 | Options 164 | ------- 165 | outdir : output directory 166 | linechunk : number of lines to process per pass; reduce only if memory is constrained 167 | class_prob : Boolean. Should we create a probability raster for each class? 168 | certainty : Boolean. Should we produce a raster of overall classification certainty? 169 | """ 170 | if not os.path.exists(outdir): 171 | os.makedirs(outdir) 172 | 173 | shape = raster_info["shape"] 174 | 175 | profile = { 176 | "blockxsize": shape[1], 177 | "height": shape[0], 178 | "blockysize": 1, 179 | "count": 1, 180 | "crs": raster_info["crs"], 181 | "driver": u"GTiff", 182 | "dtype": "int16", 183 | "nodata": -32768, 184 | "tiled": False, 185 | "transform": raster_info["transform"], 186 | "width": shape[1], 187 | } 188 | 189 | try: 190 | response_path = os.path.join(outdir, "responses.tif") 191 | response_ds = rasterio.open(response_path, "w", **profile) 192 | 193 | profile["dtype"] = "float32" 194 | if certainty: 195 | certainty_path = os.path.join(outdir, "certainty.tif") 196 | certainty_ds = rasterio.open(certainty_path, "w", **profile) 197 | 198 | class_dss = [] 199 | if class_prob: 200 | classes = list(clf.classes_) 201 | class_paths = [] 202 | for i, c in enumerate(classes): 203 | ods = os.path.join(outdir, "probability_%s.tif" % c) 204 | class_paths.append(ods) 205 | for p in class_paths: 206 | class_dss.append(rasterio.open(p, "w", **profile)) 207 | 208 | # Chunky logic 209 | if not linechunk: 210 | linechunk = shape[0] 211 | chunks = int(math.ceil(shape[0] / float(linechunk))) 212 | 213 | for chunk in range(chunks): 214 | logger.debug("Writing chunk %d of %d" % (chunk + 1, chunks)) 215 | row = chunk * linechunk 216 | if row + linechunk > shape[0]: 217 | linechunk = shape[0] - row 218 | # in 1D space 219 | start = shape[1] * row 220 | end = start + shape[1] * linechunk 221 | line = target_xs[start:end, :] 222 | 223 | window = ((row, row + linechunk), (0, shape[1])) 224 | 225 | # Predict 226 | responses = clf.predict(line) 227 | responses2D = responses.reshape((linechunk, shape[1])).astype("int16") 228 | response_ds.write_band(1, responses2D, window=window) 229 | 230 | if certainty or class_prob: 231 | proba = clf.predict_proba(line) 232 | 233 | # Certainty 234 | if certainty: 235 | certaintymax = proba.max(axis=1) 236 | certainty2D = certaintymax.reshape((linechunk, shape[1])).astype( 237 | "float32" 238 | ) 239 | certainty_ds.write_band(1, certainty2D, window=window) 240 | 241 | # write out probabilities for each class as a separate raster 242 | for i, class_ds in enumerate(class_dss): 243 | proba_class = proba[:, i] 244 | classcert2D = proba_class.reshape((linechunk, shape[1])).astype( 245 | "float32" 246 | ) 247 | class_ds.write_band(1, classcert2D, window=window) 248 | 249 | finally: 250 | response_ds.close() 251 | if certainty: 252 | certainty_ds.close() 253 | for class_ds in class_dss: 254 | class_ds.close() 255 | 256 | 257 | def stratified_sample_raster( 258 | strata_data, target_sample_size=30, min_sample_proportion=0.1 259 | ): 260 | """ 261 | Parameters 262 | ---------- 263 | strata_data: Path to raster dataset containing strata to sample from (e.g. zones) 264 | 265 | Returns 266 | ------- 267 | selected: array of selected indices 268 | """ 269 | with rasterio.open(strata_data) as src: 270 | strata = src.read().flatten() 271 | index_array = np.arange(strata.size) 272 | 273 | # construct a dictionary of lists, 274 | # keys are stratum ids 275 | # values are list of indices 276 | sample = dict([(int(s), []) for s in np.unique(strata)]) 277 | satisfied = [] 278 | 279 | # counts for proportion-based constraints 280 | bins = np.bincount(strata) 281 | ii = np.nonzero(bins)[0] 282 | stratum_count = dict(zip(ii, bins[ii])) 283 | 284 | # shuffle the indices and loop until the sample satisfied our constraints 285 | np.random.shuffle(index_array) 286 | for idx in index_array: 287 | stratum = strata[index_array[idx]] 288 | if stratum in satisfied: 289 | continue 290 | sample[stratum].append(idx) 291 | nsamples = len(sample[stratum]) 292 | # constraints -> hit the target sample size OR proportion of total 293 | # (whichever is highest) 294 | target = stratum_count[stratum] * min_sample_proportion 295 | if target < target_sample_size: 296 | target = target_sample_size 297 | if nsamples >= target: 298 | satisfied.append(stratum) 299 | if len(satisfied) == len(sample.keys()): 300 | break 301 | 302 | # convert sampled indicies into a list of indicies 303 | selected = [] 304 | for k, v in sample.items(): 305 | # check for stratum with < target sample size 306 | if len(v) < target_sample_size: 307 | # if we have too few samples, drop them 308 | # warnings.warn("Stratum %s has only %d samples, dropped" % (k, len(v))) 309 | pass 310 | else: 311 | selected.extend(v) 312 | 313 | return np.array(selected) 314 | 315 | 316 | def evaluate_clf( 317 | clf, X, y, k=None, test_size=0.5, scoring="f1_weighted", feature_names=None 318 | ): 319 | """ 320 | Evalate the classifier on the FULL training dataset 321 | This takes care of fitting on train/test splits 322 | """ 323 | X_train, X_test, y_train, y_true = model_selection.train_test_split( 324 | X, y, test_size=test_size 325 | ) 326 | 327 | clf.fit(X_train, y_train) 328 | y_pred = clf.predict(X_test) 329 | 330 | print("Accuracy Score: %f" % metrics.accuracy_score(y_true, y_pred)) 331 | print() 332 | 333 | print("Classification report") 334 | print(metrics.classification_report(y_true, y_pred)) 335 | print() 336 | 337 | print("Confussion matrix") 338 | print(metrics.confusion_matrix(y_true, y_pred)) 339 | print() 340 | 341 | if hasattr(clf, "feature_importances_"): 342 | print("Feature importances") 343 | if not feature_names: 344 | feature_names = ["%d" % i for i in range(X.shape[1])] 345 | for f, imp in zip(feature_names, clf.feature_importances_): 346 | print("%20s: %s" % (f, round(imp * 100, 1))) 347 | print() 348 | 349 | if k: 350 | print("Cross validation") 351 | kf = model_selection.KFold(n_splits=k) 352 | scores = model_selection.cross_val_score(clf, X_train, y_train, cv=kf, scoring=scoring) 353 | print(scores) 354 | print( 355 | "%d-fold Cross Validation Accuracy: %0.2f (+/- %0.2f)" 356 | % (k, scores.mean() * 100, scores.std() * 200) 357 | ) 358 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import sys 3 | logging.basicConfig(stream=sys.stderr, level=logging.INFO) 4 | -------------------------------------------------------------------------------- /tests/data/dtmean8_12.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/dtmean8_12.img -------------------------------------------------------------------------------- /tests/data/gt_dem.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/gt_dem.img -------------------------------------------------------------------------------- /tests/data/int_cnl_euc.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/int_cnl_euc.img -------------------------------------------------------------------------------- /tests/data/p_n.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/p_n.img -------------------------------------------------------------------------------- /tests/data/pmean_all.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/pmean_all.img -------------------------------------------------------------------------------- /tests/data/points.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, 4 | 5 | "features": [ 6 | { "type": "Feature", "properties": { "ID": 0, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1463188.729, 336691.011 ] } }, 7 | { "type": "Feature", "properties": { "ID": 1, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1465718.295, 410271.952 ] } }, 8 | { "type": "Feature", "properties": { "ID": 2, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1301460.662, 379186.863 ] } }, 9 | { "type": "Feature", "properties": { "ID": 3, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1387730.561, 337584.11 ] } }, 10 | { "type": "Feature", "properties": { "ID": 4, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1258831.951, 379709.525 ] } }, 11 | { "type": "Feature", "properties": { "ID": 5, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1263318.672, 319738.63 ] } }, 12 | { "type": "Feature", "properties": { "ID": 6, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1241592.093, 375085.568 ] } }, 13 | { "type": "Feature", "properties": { "ID": 7, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1466389.536, 377257.741 ] } }, 14 | { "type": "Feature", "properties": { "ID": 8, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1351556.104, 423829.108 ] } }, 15 | { "type": "Feature", "properties": { "ID": 9, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1329072.85, 299582.601 ] } }, 16 | { "type": "Feature", "properties": { "ID": 10, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1441045.538, 308082.18 ] } }, 17 | { "type": "Feature", "properties": { "ID": 11, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1332908.61, 328605.607 ] } }, 18 | { "type": "Feature", "properties": { "ID": 12, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1433075.075, 403895.646 ] } }, 19 | { "type": "Feature", "properties": { "ID": 13, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1387719.379, 426395.015 ] } }, 20 | { "type": "Feature", "properties": { "ID": 14, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1467550.995, 421824.118 ] } }, 21 | { "type": "Feature", "properties": { "ID": 15, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1343927.37, 337087.42 ] } }, 22 | { "type": "Feature", "properties": { "ID": 16, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1460726.647, 314242.616 ] } }, 23 | { "type": "Feature", "properties": { "ID": 17, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1305679.328, 395622.893 ] } }, 24 | { "type": "Feature", "properties": { "ID": 18, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1447104.86, 357007.611 ] } }, 25 | { "type": "Feature", "properties": { "ID": 19, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1248072.513, 361303.474 ] } }, 26 | { "type": "Feature", "properties": { "ID": 20, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1299466.541, 382233.947 ] } }, 27 | { "type": "Feature", "properties": { "ID": 21, "ZONE": 106 }, "geometry": { "type": "Point", "coordinates": [ -1338745.468, 284616.695 ] } }, 28 | { "type": "Feature", "properties": { "ID": 22, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1257203.063, 388938.786 ] } }, 29 | { "type": "Feature", "properties": { "ID": 23, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1290512.956, 306981.792 ] } }, 30 | { "type": "Feature", "properties": { "ID": 24, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1326730.654, 314151.007 ] } }, 31 | { "type": "Feature", "properties": { "ID": 25, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1276229.746, 390739.426 ] } }, 32 | { "type": "Feature", "properties": { "ID": 26, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1348601.048, 402980.944 ] } }, 33 | { "type": "Feature", "properties": { "ID": 27, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1372987.859, 308373.033 ] } }, 34 | { "type": "Feature", "properties": { "ID": 28, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1330185.004, 292685.571 ] } }, 35 | { "type": "Feature", "properties": { "ID": 29, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1469707.657, 388850.977 ] } }, 36 | { "type": "Feature", "properties": { "ID": 30, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1401589.678, 325541.412 ] } }, 37 | { "type": "Feature", "properties": { "ID": 31, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1255700.123, 311116.301 ] } }, 38 | { "type": "Feature", "properties": { "ID": 32, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1254766.355, 350153.813 ] } }, 39 | { "type": "Feature", "properties": { "ID": 33, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1358299.34, 350921.076 ] } }, 40 | { "type": "Feature", "properties": { "ID": 34, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1460941.667, 427040.193 ] } }, 41 | { "type": "Feature", "properties": { "ID": 35, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1371626.869, 313012.334 ] } }, 42 | { "type": "Feature", "properties": { "ID": 36, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1434219.09, 357391.142 ] } }, 43 | { "type": "Feature", "properties": { "ID": 37, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1254225.642, 358270.698 ] } }, 44 | { "type": "Feature", "properties": { "ID": 38, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1276642.463, 384202.409 ] } }, 45 | { "type": "Feature", "properties": { "ID": 39, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1415687.992, 322768.102 ] } }, 46 | { "type": "Feature", "properties": { "ID": 40, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1221800.873, 386281.649 ] } }, 47 | { "type": "Feature", "properties": { "ID": 41, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1404790.19, 385641.528 ] } }, 48 | { "type": "Feature", "properties": { "ID": 42, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1298003.136, 332114.895 ] } }, 49 | { "type": "Feature", "properties": { "ID": 43, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1396474.187, 408761.638 ] } }, 50 | { "type": "Feature", "properties": { "ID": 44, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1456870.711, 314717.207 ] } }, 51 | { "type": "Feature", "properties": { "ID": 45, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1298548.452, 352402.541 ] } }, 52 | { "type": "Feature", "properties": { "ID": 46, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1235155.139, 305473.463 ] } }, 53 | { "type": "Feature", "properties": { "ID": 47, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1450157.554, 392261.539 ] } }, 54 | { "type": "Feature", "properties": { "ID": 48, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1431649.447, 291298.757 ] } }, 55 | { "type": "Feature", "properties": { "ID": 49, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1253844.653, 332532.475 ] } }, 56 | { "type": "Feature", "properties": { "ID": 50, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1256302.272, 413831.943 ] } }, 57 | { "type": "Feature", "properties": { "ID": 51, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1249628.061, 410892.124 ] } }, 58 | { "type": "Feature", "properties": { "ID": 52, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1467523.451, 296320.244 ] } }, 59 | { "type": "Feature", "properties": { "ID": 53, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1278670.971, 402410.667 ] } }, 60 | { "type": "Feature", "properties": { "ID": 54, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1367433.157, 387524.251 ] } }, 61 | { "type": "Feature", "properties": { "ID": 55, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1251593.311, 327494.97 ] } }, 62 | { "type": "Feature", "properties": { "ID": 56, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1444403.766, 412538.481 ] } }, 63 | { "type": "Feature", "properties": { "ID": 57, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1373716.0, 376943.862 ] } }, 64 | { "type": "Feature", "properties": { "ID": 58, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1471993.819, 355254.55 ] } }, 65 | { "type": "Feature", "properties": { "ID": 59, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1465121.489, 368374.298 ] } }, 66 | { "type": "Feature", "properties": { "ID": 60, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1288599.931, 328926.369 ] } }, 67 | { "type": "Feature", "properties": { "ID": 61, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1450672.156, 358646.295 ] } }, 68 | { "type": "Feature", "properties": { "ID": 62, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1445215.327, 404493.677 ] } }, 69 | { "type": "Feature", "properties": { "ID": 63, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1429686.332, 381256.995 ] } }, 70 | { "type": "Feature", "properties": { "ID": 64, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1323226.72, 422068.113 ] } }, 71 | { "type": "Feature", "properties": { "ID": 65, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1280969.597, 408790.904 ] } }, 72 | { "type": "Feature", "properties": { "ID": 66, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1262739.553, 317797.257 ] } }, 73 | { "type": "Feature", "properties": { "ID": 67, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1299835.151, 376786.497 ] } }, 74 | { "type": "Feature", "properties": { "ID": 68, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1471863.253, 372964.584 ] } }, 75 | { "type": "Feature", "properties": { "ID": 69, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1393194.026, 347330.326 ] } }, 76 | { "type": "Feature", "properties": { "ID": 70, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1345020.45, 406397.101 ] } }, 77 | { "type": "Feature", "properties": { "ID": 71, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1360184.908, 386255.668 ] } }, 78 | { "type": "Feature", "properties": { "ID": 72, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1374547.942, 308373.127 ] } }, 79 | { "type": "Feature", "properties": { "ID": 73, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1471367.734, 352060.693 ] } }, 80 | { "type": "Feature", "properties": { "ID": 74, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1259636.007, 316453.244 ] } }, 81 | { "type": "Feature", "properties": { "ID": 75, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1366646.514, 362748.244 ] } }, 82 | { "type": "Feature", "properties": { "ID": 76, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1274024.401, 303737.17 ] } }, 83 | { "type": "Feature", "properties": { "ID": 77, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1299181.393, 314775.302 ] } }, 84 | { "type": "Feature", "properties": { "ID": 78, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1396491.173, 335380.608 ] } }, 85 | { "type": "Feature", "properties": { "ID": 79, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1330428.996, 368456.355 ] } }, 86 | { "type": "Feature", "properties": { "ID": 80, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1265563.458, 353233.863 ] } }, 87 | { "type": "Feature", "properties": { "ID": 81, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1386875.314, 365638.165 ] } }, 88 | { "type": "Feature", "properties": { "ID": 82, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1430502.774, 327245.857 ] } }, 89 | { "type": "Feature", "properties": { "ID": 83, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1396138.93, 301227.123 ] } }, 90 | { "type": "Feature", "properties": { "ID": 84, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1239368.158, 286896.625 ] } }, 91 | { "type": "Feature", "properties": { "ID": 85, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1261466.347, 285696.525 ] } }, 92 | { "type": "Feature", "properties": { "ID": 86, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1395233.017, 405925.562 ] } }, 93 | { "type": "Feature", "properties": { "ID": 87, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1392857.007, 360898.086 ] } }, 94 | { "type": "Feature", "properties": { "ID": 88, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1364315.518, 326636.967 ] } }, 95 | { "type": "Feature", "properties": { "ID": 89, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1348565.312, 371211.7 ] } }, 96 | { "type": "Feature", "properties": { "ID": 90, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1374316.109, 414643.921 ] } }, 97 | { "type": "Feature", "properties": { "ID": 91, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1393160.269, 354383.616 ] } }, 98 | { "type": "Feature", "properties": { "ID": 92, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1323184.629, 286034.173 ] } }, 99 | { "type": "Feature", "properties": { "ID": 93, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1375415.924, 381610.904 ] } }, 100 | { "type": "Feature", "properties": { "ID": 94, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1455398.502, 385361.079 ] } }, 101 | { "type": "Feature", "properties": { "ID": 95, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1264140.77, 424257.37 ] } }, 102 | { "type": "Feature", "properties": { "ID": 96, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1285065.864, 354251.609 ] } }, 103 | { "type": "Feature", "properties": { "ID": 97, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1385053.068, 386127.615 ] } }, 104 | { "type": "Feature", "properties": { "ID": 98, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1411806.854, 406195.119 ] } }, 105 | { "type": "Feature", "properties": { "ID": 99, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1288297.964, 340477.633 ] } }, 106 | { "type": "Feature", "properties": { "ID": 100, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1225142.552, 363533.25 ] } }, 107 | { "type": "Feature", "properties": { "ID": 101, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1311973.017, 376077.321 ] } }, 108 | { "type": "Feature", "properties": { "ID": 102, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1406746.006, 329545.469 ] } }, 109 | { "type": "Feature", "properties": { "ID": 103, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1463536.892, 401459.44 ] } }, 110 | { "type": "Feature", "properties": { "ID": 104, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1233101.17, 305832.764 ] } }, 111 | { "type": "Feature", "properties": { "ID": 105, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1358035.231, 363659.882 ] } }, 112 | { "type": "Feature", "properties": { "ID": 106, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1344594.317, 311060.478 ] } }, 113 | { "type": "Feature", "properties": { "ID": 107, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1481170.407, 387751.828 ] } }, 114 | { "type": "Feature", "properties": { "ID": 108, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1333854.64, 361413.021 ] } }, 115 | { "type": "Feature", "properties": { "ID": 109, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1323528.57, 320347.024 ] } }, 116 | { "type": "Feature", "properties": { "ID": 110, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1437455.892, 378115.411 ] } }, 117 | { "type": "Feature", "properties": { "ID": 111, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1406940.463, 427212.749 ] } }, 118 | { "type": "Feature", "properties": { "ID": 112, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1250807.879, 328637.275 ] } }, 119 | { "type": "Feature", "properties": { "ID": 113, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1243899.434, 372948.998 ] } }, 120 | { "type": "Feature", "properties": { "ID": 114, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1480346.387, 301774.144 ] } }, 121 | { "type": "Feature", "properties": { "ID": 115, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1464858.203, 356765.078 ] } }, 122 | { "type": "Feature", "properties": { "ID": 116, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1449527.241, 416141.21 ] } }, 123 | { "type": "Feature", "properties": { "ID": 117, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1333634.993, 363454.639 ] } }, 124 | { "type": "Feature", "properties": { "ID": 118, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1457308.935, 344545.403 ] } }, 125 | { "type": "Feature", "properties": { "ID": 119, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1308011.125, 397032.998 ] } }, 126 | { "type": "Feature", "properties": { "ID": 120, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1291283.454, 401303.67 ] } }, 127 | { "type": "Feature", "properties": { "ID": 121, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1437792.206, 323309.501 ] } }, 128 | { "type": "Feature", "properties": { "ID": 122, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1470058.385, 402208.252 ] } }, 129 | { "type": "Feature", "properties": { "ID": 123, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1326115.837, 296094.061 ] } }, 130 | { "type": "Feature", "properties": { "ID": 124, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1366629.98, 331202.29 ] } }, 131 | { "type": "Feature", "properties": { "ID": 125, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1443574.361, 383468.349 ] } }, 132 | { "type": "Feature", "properties": { "ID": 126, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1237298.45, 389032.313 ] } }, 133 | { "type": "Feature", "properties": { "ID": 127, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1245077.375, 398700.761 ] } }, 134 | { "type": "Feature", "properties": { "ID": 128, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1341140.514, 351927.428 ] } }, 135 | { "type": "Feature", "properties": { "ID": 129, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1272392.246, 322876.598 ] } }, 136 | { "type": "Feature", "properties": { "ID": 130, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1398417.851, 356914.003 ] } }, 137 | { "type": "Feature", "properties": { "ID": 131, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1299526.364, 384999.3 ] } }, 138 | { "type": "Feature", "properties": { "ID": 132, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1264418.183, 299045.396 ] } }, 139 | { "type": "Feature", "properties": { "ID": 133, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1215981.737, 293885.014 ] } }, 140 | { "type": "Feature", "properties": { "ID": 134, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1409014.987, 284587.599 ] } }, 141 | { "type": "Feature", "properties": { "ID": 135, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1399613.867, 402674.288 ] } }, 142 | { "type": "Feature", "properties": { "ID": 136, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1224364.281, 342774.767 ] } }, 143 | { "type": "Feature", "properties": { "ID": 137, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1337885.677, 404982.807 ] } }, 144 | { "type": "Feature", "properties": { "ID": 138, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1316774.369, 397456.231 ] } }, 145 | { "type": "Feature", "properties": { "ID": 139, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1299130.792, 319290.967 ] } }, 146 | { "type": "Feature", "properties": { "ID": 140, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1318938.992, 386869.335 ] } }, 147 | { "type": "Feature", "properties": { "ID": 141, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1279113.033, 293449.5 ] } }, 148 | { "type": "Feature", "properties": { "ID": 142, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1421199.06, 314596.861 ] } }, 149 | { "type": "Feature", "properties": { "ID": 143, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1475529.218, 321726.876 ] } }, 150 | { "type": "Feature", "properties": { "ID": 144, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1409537.984, 318625.061 ] } }, 151 | { "type": "Feature", "properties": { "ID": 145, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1315888.474, 303726.39 ] } }, 152 | { "type": "Feature", "properties": { "ID": 146, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1318440.886, 381784.092 ] } }, 153 | { "type": "Feature", "properties": { "ID": 147, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1351812.994, 382245.949 ] } }, 154 | { "type": "Feature", "properties": { "ID": 148, "ZONE": 97 }, "geometry": { "type": "Point", "coordinates": [ -1295675.023, 426573.977 ] } }, 155 | { "type": "Feature", "properties": { "ID": 149, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1416728.886, 289873.43 ] } }, 156 | { "type": "Feature", "properties": { "ID": 150, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1222267.408, 341219.735 ] } }, 157 | { "type": "Feature", "properties": { "ID": 151, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1378613.249, 326953.596 ] } }, 158 | { "type": "Feature", "properties": { "ID": 152, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1253402.821, 349918.711 ] } }, 159 | { "type": "Feature", "properties": { "ID": 153, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1370493.52, 387789.782 ] } }, 160 | { "type": "Feature", "properties": { "ID": 154, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1481643.675, 378130.237 ] } }, 161 | { "type": "Feature", "properties": { "ID": 155, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1264490.767, 401642.982 ] } }, 162 | { "type": "Feature", "properties": { "ID": 156, "ZONE": 97 }, "geometry": { "type": "Point", "coordinates": [ -1303835.649, 407028.475 ] } }, 163 | { "type": "Feature", "properties": { "ID": 157, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1351252.23, 369177.655 ] } }, 164 | { "type": "Feature", "properties": { "ID": 158, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1258303.09, 365899.816 ] } }, 165 | { "type": "Feature", "properties": { "ID": 159, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1273477.51, 411440.178 ] } }, 166 | { "type": "Feature", "properties": { "ID": 160, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1316990.458, 327398.716 ] } }, 167 | { "type": "Feature", "properties": { "ID": 161, "ZONE": 97 }, "geometry": { "type": "Point", "coordinates": [ -1362939.218, 425430.016 ] } }, 168 | { "type": "Feature", "properties": { "ID": 162, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1375348.203, 323209.512 ] } }, 169 | { "type": "Feature", "properties": { "ID": 163, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1321197.477, 419279.794 ] } }, 170 | { "type": "Feature", "properties": { "ID": 164, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1223650.074, 284944.142 ] } }, 171 | { "type": "Feature", "properties": { "ID": 165, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1440975.363, 408886.531 ] } }, 172 | { "type": "Feature", "properties": { "ID": 166, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1443040.36, 346547.415 ] } }, 173 | { "type": "Feature", "properties": { "ID": 167, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1427110.895, 377950.28 ] } }, 174 | { "type": "Feature", "properties": { "ID": 168, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1389903.246, 287446.14 ] } }, 175 | { "type": "Feature", "properties": { "ID": 169, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1369927.952, 390657.725 ] } }, 176 | { "type": "Feature", "properties": { "ID": 170, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1369878.079, 309301.7 ] } }, 177 | { "type": "Feature", "properties": { "ID": 171, "ZONE": 97 }, "geometry": { "type": "Point", "coordinates": [ -1363517.475, 420121.023 ] } }, 178 | { "type": "Feature", "properties": { "ID": 172, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1344755.836, 339415.605 ] } }, 179 | { "type": "Feature", "properties": { "ID": 173, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1347443.101, 374621.521 ] } }, 180 | { "type": "Feature", "properties": { "ID": 174, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1414846.741, 344681.726 ] } }, 181 | { "type": "Feature", "properties": { "ID": 175, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1418792.767, 392851.377 ] } }, 182 | { "type": "Feature", "properties": { "ID": 176, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1367927.318, 367120.848 ] } }, 183 | { "type": "Feature", "properties": { "ID": 177, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1329851.0, 296985.363 ] } }, 184 | { "type": "Feature", "properties": { "ID": 178, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1235287.167, 354011.641 ] } }, 185 | { "type": "Feature", "properties": { "ID": 179, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1266488.526, 409677.49 ] } }, 186 | { "type": "Feature", "properties": { "ID": 180, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1321997.561, 318854.75 ] } }, 187 | { "type": "Feature", "properties": { "ID": 181, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1406331.646, 409739.314 ] } }, 188 | { "type": "Feature", "properties": { "ID": 182, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1448913.629, 380275.039 ] } }, 189 | { "type": "Feature", "properties": { "ID": 183, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1446339.452, 364503.295 ] } }, 190 | { "type": "Feature", "properties": { "ID": 184, "ZONE": 97 }, "geometry": { "type": "Point", "coordinates": [ -1308488.807, 405743.652 ] } }, 191 | { "type": "Feature", "properties": { "ID": 185, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1435502.859, 334352.563 ] } }, 192 | { "type": "Feature", "properties": { "ID": 186, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1268588.457, 417309.722 ] } }, 193 | { "type": "Feature", "properties": { "ID": 187, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1294319.408, 388431.045 ] } }, 194 | { "type": "Feature", "properties": { "ID": 188, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1344489.764, 380289.251 ] } }, 195 | { "type": "Feature", "properties": { "ID": 189, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1279974.412, 306026.821 ] } }, 196 | { "type": "Feature", "properties": { "ID": 190, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1315537.473, 401728.521 ] } }, 197 | { "type": "Feature", "properties": { "ID": 191, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1328041.157, 399991.698 ] } }, 198 | { "type": "Feature", "properties": { "ID": 192, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1432027.133, 393339.835 ] } }, 199 | { "type": "Feature", "properties": { "ID": 193, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1326603.104, 284842.88 ] } }, 200 | { "type": "Feature", "properties": { "ID": 194, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1422252.838, 306691.677 ] } }, 201 | { "type": "Feature", "properties": { "ID": 195, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1302148.449, 325004.702 ] } }, 202 | { "type": "Feature", "properties": { "ID": 196, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1371933.877, 343237.963 ] } }, 203 | { "type": "Feature", "properties": { "ID": 197, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1264543.23, 324546.686 ] } }, 204 | { "type": "Feature", "properties": { "ID": 198, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1239248.465, 394642.763 ] } }, 205 | { "type": "Feature", "properties": { "ID": 199, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1441613.543, 393955.215 ] } }, 206 | { "type": "Feature", "properties": { "ID": 200, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1292502.982, 422898.962 ] } }, 207 | { "type": "Feature", "properties": { "ID": 201, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1283028.394, 374241.23 ] } }, 208 | { "type": "Feature", "properties": { "ID": 202, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1412494.012, 406146.142 ] } }, 209 | { "type": "Feature", "properties": { "ID": 203, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1259845.215, 417471.585 ] } }, 210 | { "type": "Feature", "properties": { "ID": 204, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1272067.407, 395656.415 ] } }, 211 | { "type": "Feature", "properties": { "ID": 205, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1267580.914, 369867.174 ] } }, 212 | { "type": "Feature", "properties": { "ID": 206, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1407156.67, 388305.66 ] } }, 213 | { "type": "Feature", "properties": { "ID": 207, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1479645.7, 422960.232 ] } }, 214 | { "type": "Feature", "properties": { "ID": 208, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1434378.086, 369167.271 ] } }, 215 | { "type": "Feature", "properties": { "ID": 209, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1370391.683, 303636.563 ] } }, 216 | { "type": "Feature", "properties": { "ID": 210, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1441877.46, 287139.684 ] } }, 217 | { "type": "Feature", "properties": { "ID": 211, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1436660.053, 422004.931 ] } }, 218 | { "type": "Feature", "properties": { "ID": 212, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1468502.928, 383320.473 ] } }, 219 | { "type": "Feature", "properties": { "ID": 213, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1221047.361, 411871.139 ] } }, 220 | { "type": "Feature", "properties": { "ID": 214, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1392093.43, 398079.935 ] } }, 221 | { "type": "Feature", "properties": { "ID": 215, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1320097.92, 380295.027 ] } }, 222 | { "type": "Feature", "properties": { "ID": 216, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1425545.293, 361658.506 ] } }, 223 | { "type": "Feature", "properties": { "ID": 217, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1363501.555, 377882.272 ] } }, 224 | { "type": "Feature", "properties": { "ID": 218, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1436982.306, 289744.736 ] } }, 225 | { "type": "Feature", "properties": { "ID": 219, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1309197.886, 345386.066 ] } }, 226 | { "type": "Feature", "properties": { "ID": 220, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1405119.888, 396623.29 ] } }, 227 | { "type": "Feature", "properties": { "ID": 221, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1303221.702, 315828.504 ] } }, 228 | { "type": "Feature", "properties": { "ID": 222, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1220966.429, 388105.783 ] } }, 229 | { "type": "Feature", "properties": { "ID": 223, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1442179.055, 287235.236 ] } }, 230 | { "type": "Feature", "properties": { "ID": 224, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1405209.09, 303000.469 ] } }, 231 | { "type": "Feature", "properties": { "ID": 225, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1272479.506, 309112.835 ] } }, 232 | { "type": "Feature", "properties": { "ID": 226, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1442297.126, 425528.607 ] } }, 233 | { "type": "Feature", "properties": { "ID": 227, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1370994.272, 388931.88 ] } }, 234 | { "type": "Feature", "properties": { "ID": 228, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1244988.584, 404251.188 ] } }, 235 | { "type": "Feature", "properties": { "ID": 229, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1448327.865, 358328.463 ] } }, 236 | { "type": "Feature", "properties": { "ID": 230, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1272061.205, 384220.435 ] } }, 237 | { "type": "Feature", "properties": { "ID": 231, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1351677.566, 349321.865 ] } }, 238 | { "type": "Feature", "properties": { "ID": 232, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1326264.71, 291534.292 ] } }, 239 | { "type": "Feature", "properties": { "ID": 233, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1309258.543, 287884.663 ] } }, 240 | { "type": "Feature", "properties": { "ID": 234, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1283895.0, 407826.679 ] } }, 241 | { "type": "Feature", "properties": { "ID": 235, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1260283.109, 322246.004 ] } }, 242 | { "type": "Feature", "properties": { "ID": 236, "ZONE": 70 }, "geometry": { "type": "Point", "coordinates": [ -1287929.575, 301348.838 ] } }, 243 | { "type": "Feature", "properties": { "ID": 237, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1362544.693, 291178.086 ] } }, 244 | { "type": "Feature", "properties": { "ID": 238, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1237829.415, 303814.231 ] } }, 245 | { "type": "Feature", "properties": { "ID": 239, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1276075.461, 338746.1 ] } }, 246 | { "type": "Feature", "properties": { "ID": 240, "ZONE": 105 }, "geometry": { "type": "Point", "coordinates": [ -1304161.164, 290060.151 ] } }, 247 | { "type": "Feature", "properties": { "ID": 241, "ZONE": 187 }, "geometry": { "type": "Point", "coordinates": [ -1389992.241, 362634.747 ] } }, 248 | { "type": "Feature", "properties": { "ID": 242, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1423853.182, 417237.575 ] } }, 249 | { "type": "Feature", "properties": { "ID": 243, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1425633.092, 336468.111 ] } }, 250 | { "type": "Feature", "properties": { "ID": 244, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1433441.174, 297186.159 ] } }, 251 | { "type": "Feature", "properties": { "ID": 245, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1458809.726, 353234.098 ] } }, 252 | { "type": "Feature", "properties": { "ID": 246, "ZONE": 104 }, "geometry": { "type": "Point", "coordinates": [ -1314178.045, 308732.54 ] } }, 253 | { "type": "Feature", "properties": { "ID": 247, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1266026.311, 403319.265 ] } }, 254 | { "type": "Feature", "properties": { "ID": 248, "ZONE": 88 }, "geometry": { "type": "Point", "coordinates": [ -1229895.049, 405940.582 ] } }, 255 | { "type": "Feature", "properties": { "ID": 249, "ZONE": 95 }, "geometry": { "type": "Point", "coordinates": [ -1476665.593, 286837.895 ] } } 256 | ] 257 | } 258 | -------------------------------------------------------------------------------- /tests/data/responses.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/responses.tif -------------------------------------------------------------------------------- /tests/data/tmax8.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/tmax8.img -------------------------------------------------------------------------------- /tests/data/tmean_all.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perrygeo/pyimpute/e2e9f4ef33a954494abbafeec26b4a123be05d6e/tests/data/tmean_all.img -------------------------------------------------------------------------------- /tests/test_impute.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data") 4 | explanatory_rasters = [ 5 | os.path.join(DATA, x) 6 | for x in "dtmean8_12.img gt_dem.img int_cnl_euc.img pmean_all.img " 7 | "p_n.img tmax8.img tmean_all.img".split() 8 | ] 9 | response_raster = os.path.join(DATA, "responses.tif") 10 | TMPOUT = "/tmp/pyimpute_test" 11 | 12 | # Integration tests demonstrating a simplified example 13 | 14 | 15 | def test_impute(): 16 | from pyimpute import load_training_rasters, load_targets, impute 17 | 18 | # Load training data 19 | train_xs, train_y = load_training_rasters(response_raster, explanatory_rasters) 20 | 21 | # Train a classifier 22 | from sklearn.ensemble import RandomForestClassifier 23 | 24 | clf = RandomForestClassifier(n_estimators=10, n_jobs=1) 25 | clf.fit(train_xs, train_y) 26 | 27 | # Load targets 28 | target_xs, raster_info = load_targets(explanatory_rasters) 29 | 30 | # Go... 31 | impute( 32 | target_xs, 33 | clf, 34 | raster_info, 35 | outdir=TMPOUT, 36 | linechunk=400, 37 | class_prob=True, 38 | certainty=True, 39 | ) 40 | 41 | assert os.path.exists(os.path.join(TMPOUT, "responses.tif")) 42 | assert os.path.exists(os.path.join(TMPOUT, "certainty.tif")) 43 | assert os.path.exists(os.path.join(TMPOUT, "probability_90.tif")) 44 | 45 | 46 | def test_load_training_rasters(): 47 | from pyimpute import load_training_rasters 48 | 49 | train_xs, train_y = load_training_rasters(response_raster, explanatory_rasters) 50 | assert train_xs.shape == (38304, 7) 51 | assert len(explanatory_rasters) == train_xs.shape[1] 52 | assert train_y.shape == (38304,) 53 | 54 | 55 | def test_load_training_vector(): 56 | from pyimpute import load_training_vector 57 | 58 | response_shapes = os.path.join(DATA, "points.geojson") 59 | 60 | train_xs, train_y = load_training_vector( 61 | response_shapes, explanatory_rasters, response_field="ZONE" 62 | ) 63 | 64 | assert train_xs.shape == (250, 7) 65 | assert train_y.shape == (250,) 66 | 67 | 68 | def test_load_targets(): 69 | from pyimpute import load_targets 70 | 71 | target_xs, raster_info = load_targets(explanatory_rasters) 72 | assert sorted(raster_info.keys()) == ["crs", "shape", "transform"] 73 | assert target_xs.shape == (38304, 7) 74 | 75 | 76 | def test_stratified_sample_raster(): 77 | from pyimpute import load_training_rasters, stratified_sample_raster 78 | 79 | # Take a random stratified sample 80 | selected = stratified_sample_raster( 81 | response_raster, target_sample_size=20, min_sample_proportion=0.1 82 | ) 83 | assert selected.shape == (3849,) 84 | 85 | train_xs, train_y = load_training_rasters( 86 | response_raster, explanatory_rasters, selected 87 | ) 88 | assert train_xs.shape == (3849, 7) 89 | assert train_y.shape == (3849,) 90 | --------------------------------------------------------------------------------