├── .github └── workflows │ ├── build-publish-mac.yml │ ├── build-publish-ubuntu.yml │ └── win-build-publish.yml ├── .gitignore ├── .gitmodules ├── Development.md ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── build.sh ├── data ├── Guerry.dbf ├── Guerry.prj ├── Guerry.shp ├── Guerry.shx ├── chicago_comm.dbf ├── chicago_comm.prj ├── chicago_comm.shp ├── chicago_comm.shx ├── columbus.dbf ├── columbus.prj ├── columbus.shp ├── columbus.shx ├── natregimes.dbf ├── natregimes.prj ├── natregimes.shp └── natregimes.shx ├── docs ├── .buildinfo ├── .nojekyll ├── _modules │ ├── index.html │ └── pygeoda │ │ ├── classify │ │ └── breaks.html │ │ ├── clustering │ │ ├── azp.html │ │ ├── maxp.html │ │ ├── redcap.html │ │ ├── schc.html │ │ ├── skater.html │ │ └── validation.html │ │ ├── data │ │ └── transform.html │ │ ├── gda.html │ │ ├── sa │ │ ├── geary.html │ │ ├── getisord.html │ │ ├── joincount.html │ │ ├── lisa.html │ │ ├── moran.html │ │ ├── neighbor_match_test.html │ │ └── quantile_lisa.html │ │ └── weights │ │ ├── distance.html │ │ ├── kernel.html │ │ ├── queen.html │ │ ├── rook.html │ │ └── weight.html ├── _sources │ ├── api.rst.txt │ ├── esda_geopandas.rst.txt │ ├── generated │ │ ├── pygeoda.Compactness.rst.txt │ │ ├── pygeoda.Diameter.rst.txt │ │ ├── pygeoda.Fragmentation.rst.txt │ │ ├── pygeoda.JoinCountRatio.rst.txt │ │ ├── pygeoda.PCA.rst.txt │ │ ├── pygeoda.ValidationResult.rst.txt │ │ ├── pygeoda.Weight.rst.txt │ │ ├── pygeoda.azp_greedy.rst.txt │ │ ├── pygeoda.azp_sa.rst.txt │ │ ├── pygeoda.azp_tabu.rst.txt │ │ ├── pygeoda.batch_local_moran.rst.txt │ │ ├── pygeoda.batchlisa.rst.txt │ │ ├── pygeoda.between_sumofsquare.rst.txt │ │ ├── pygeoda.clustering.maxp.rst.txt │ │ ├── pygeoda.clustering.redcap.rst.txt │ │ ├── pygeoda.clustering.skater.rst.txt │ │ ├── pygeoda.demean.rst.txt │ │ ├── pygeoda.distance_weights.rst.txt │ │ ├── pygeoda.geoda.rst.txt │ │ ├── pygeoda.geoda_to_geopandas.rst.txt │ │ ├── pygeoda.geopandas_to_geoda.rst.txt │ │ ├── pygeoda.hinge15_breaks.rst.txt │ │ ├── pygeoda.hinge30_breaks.rst.txt │ │ ├── pygeoda.kernel_knn_weights.rst.txt │ │ ├── pygeoda.kernel_weights.rst.txt │ │ ├── pygeoda.knn_weights.rst.txt │ │ ├── pygeoda.lisa.rst.txt │ │ ├── pygeoda.local_bijoincount.rst.txt │ │ ├── pygeoda.local_bimoran.rst.txt │ │ ├── pygeoda.local_g.rst.txt │ │ ├── pygeoda.local_geary.rst.txt │ │ ├── pygeoda.local_gstar.rst.txt │ │ ├── pygeoda.local_joincount.rst.txt │ │ ├── pygeoda.local_moran.rst.txt │ │ ├── pygeoda.local_multigeary.rst.txt │ │ ├── pygeoda.local_multijoincount.rst.txt │ │ ├── pygeoda.local_multiquantilelisa.rst.txt │ │ ├── pygeoda.local_quantilelisa.rst.txt │ │ ├── pygeoda.mad.rst.txt │ │ ├── pygeoda.make_spatial.rst.txt │ │ ├── pygeoda.maxp.rst.txt │ │ ├── pygeoda.maxp_greedy.rst.txt │ │ ├── pygeoda.maxp_sa.rst.txt │ │ ├── pygeoda.maxp_tabu.rst.txt │ │ ├── pygeoda.mds.rst.txt │ │ ├── pygeoda.min_distthreshold.rst.txt │ │ ├── pygeoda.natural_breaks.rst.txt │ │ ├── pygeoda.neighbor_match_test.rst.txt │ │ ├── pygeoda.open.rst.txt │ │ ├── pygeoda.percentile_breaks.rst.txt │ │ ├── pygeoda.quantile_breaks.rst.txt │ │ ├── pygeoda.quantile_lisa.rst.txt │ │ ├── pygeoda.queen_weights.rst.txt │ │ ├── pygeoda.redcap.rst.txt │ │ ├── pygeoda.rook_weights.rst.txt │ │ ├── pygeoda.sa.lisa.rst.txt │ │ ├── pygeoda.sa.local_g.rst.txt │ │ ├── pygeoda.sa.local_geary.rst.txt │ │ ├── pygeoda.sa.local_gstar.rst.txt │ │ ├── pygeoda.sa.local_joincount.rst.txt │ │ ├── pygeoda.sa.local_moran.rst.txt │ │ ├── pygeoda.schc.rst.txt │ │ ├── pygeoda.skater.rst.txt │ │ ├── pygeoda.spatial_validation.rst.txt │ │ ├── pygeoda.standardize.rst.txt │ │ ├── pygeoda.stddev_breaks.rst.txt │ │ ├── pygeoda.total_sumofsquare.rst.txt │ │ ├── pygeoda.weights.Weight.rst.txt │ │ ├── pygeoda.weights.distance.rst.txt │ │ ├── pygeoda.weights.kernel.rst.txt │ │ ├── pygeoda.weights.knn.rst.txt │ │ ├── pygeoda.weights.queen.rst.txt │ │ ├── pygeoda.weights.rook.rst.txt │ │ └── pygeoda.within_sumofsquare.rst.txt │ ├── index.rst.txt │ ├── install.rst.txt │ ├── intro.rst.txt │ ├── load_data.rst.txt │ ├── map_classification.rst.txt │ ├── spatial_auto.rst.txt │ ├── spatial_clustering.rst.txt │ └── spatial_weights.rst.txt ├── _static │ ├── basic.css │ ├── css │ │ ├── badge_only.css │ │ ├── fonts │ │ │ ├── Roboto-Slab-Bold.woff │ │ │ ├── Roboto-Slab-Bold.woff2 │ │ │ ├── Roboto-Slab-Regular.woff │ │ │ ├── Roboto-Slab-Regular.woff2 │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── fontawesome-webfont.woff2 │ │ │ ├── lato-bold-italic.woff │ │ │ ├── lato-bold-italic.woff2 │ │ │ ├── lato-bold.woff │ │ │ ├── lato-bold.woff2 │ │ │ ├── lato-normal-italic.woff │ │ │ ├── lato-normal-italic.woff2 │ │ │ ├── lato-normal.woff │ │ │ └── lato-normal.woff2 │ │ └── theme.css │ ├── doctools.js │ ├── documentation_options.js │ ├── file.png │ ├── fonts │ │ ├── Inconsolata-Bold.ttf │ │ ├── Inconsolata-Regular.ttf │ │ ├── Inconsolata.ttf │ │ ├── Lato-Bold.ttf │ │ ├── Lato-Regular.ttf │ │ ├── Lato │ │ │ ├── lato-bold.eot │ │ │ ├── lato-bold.ttf │ │ │ ├── lato-bold.woff │ │ │ ├── lato-bold.woff2 │ │ │ ├── lato-bolditalic.eot │ │ │ ├── lato-bolditalic.ttf │ │ │ ├── lato-bolditalic.woff │ │ │ ├── lato-bolditalic.woff2 │ │ │ ├── lato-italic.eot │ │ │ ├── lato-italic.ttf │ │ │ ├── lato-italic.woff │ │ │ ├── lato-italic.woff2 │ │ │ ├── lato-regular.eot │ │ │ ├── lato-regular.ttf │ │ │ ├── lato-regular.woff │ │ │ └── lato-regular.woff2 │ │ ├── RobotoSlab-Bold.ttf │ │ ├── RobotoSlab-Regular.ttf │ │ ├── RobotoSlab │ │ │ ├── roboto-slab-v7-bold.eot │ │ │ ├── roboto-slab-v7-bold.ttf │ │ │ ├── roboto-slab-v7-bold.woff │ │ │ ├── roboto-slab-v7-bold.woff2 │ │ │ ├── roboto-slab-v7-regular.eot │ │ │ ├── roboto-slab-v7-regular.ttf │ │ │ ├── roboto-slab-v7-regular.woff │ │ │ └── roboto-slab-v7-regular.woff2 │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── jquery-3.5.1.js │ ├── jquery.js │ ├── js │ │ ├── badge_only.js │ │ ├── html5shiv-printshiv.min.js │ │ ├── html5shiv.min.js │ │ ├── modernizr.min.js │ │ └── theme.js │ ├── language_data.js │ ├── minus.png │ ├── plus.png │ ├── pygments.css │ ├── searchtools.js │ ├── underscore-1.12.0.js │ ├── underscore-1.13.1.js │ └── underscore.js ├── api.html ├── esda_geopandas.html ├── generated │ ├── pygeoda.Compactness.html │ ├── pygeoda.Diameter.html │ ├── pygeoda.Fragmentation.html │ ├── pygeoda.JoinCountRatio.html │ ├── pygeoda.PCA.html │ ├── pygeoda.ValidationResult.html │ ├── pygeoda.Weight.html │ ├── pygeoda.azp_greedy.html │ ├── pygeoda.azp_sa.html │ ├── pygeoda.azp_tabu.html │ ├── pygeoda.batch_local_moran.html │ ├── pygeoda.batchlisa.html │ ├── pygeoda.between_sumofsquare.html │ ├── pygeoda.clustering.maxp.html │ ├── pygeoda.clustering.redcap.html │ ├── pygeoda.clustering.skater.html │ ├── pygeoda.demean.html │ ├── pygeoda.distance_weights.html │ ├── pygeoda.geoda.html │ ├── pygeoda.geoda_to_geopandas.html │ ├── pygeoda.geopandas_to_geoda.html │ ├── pygeoda.hinge15_breaks.html │ ├── pygeoda.hinge30_breaks.html │ ├── pygeoda.kernel_knn_weights.html │ ├── pygeoda.kernel_weights.html │ ├── pygeoda.knn_weights.html │ ├── pygeoda.lisa.html │ ├── pygeoda.local_bijoincount.html │ ├── pygeoda.local_bimoran.html │ ├── pygeoda.local_g.html │ ├── pygeoda.local_geary.html │ ├── pygeoda.local_gstar.html │ ├── pygeoda.local_joincount.html │ ├── pygeoda.local_moran.html │ ├── pygeoda.local_multigeary.html │ ├── pygeoda.local_multijoincount.html │ ├── pygeoda.local_multiquantilelisa.html │ ├── pygeoda.local_quantilelisa.html │ ├── pygeoda.mad.html │ ├── pygeoda.make_spatial.html │ ├── pygeoda.maxp.html │ ├── pygeoda.maxp_greedy.html │ ├── pygeoda.maxp_sa.html │ ├── pygeoda.maxp_tabu.html │ ├── pygeoda.mds.html │ ├── pygeoda.min_distthreshold.html │ ├── pygeoda.natural_breaks.html │ ├── pygeoda.neighbor_match_test.html │ ├── pygeoda.open.html │ ├── pygeoda.percentile_breaks.html │ ├── pygeoda.quantile_breaks.html │ ├── pygeoda.quantile_lisa.html │ ├── pygeoda.queen_weights.html │ ├── pygeoda.redcap.html │ ├── pygeoda.rook_weights.html │ ├── pygeoda.sa.lisa.html │ ├── pygeoda.sa.local_g.html │ ├── pygeoda.sa.local_geary.html │ ├── pygeoda.sa.local_gstar.html │ ├── pygeoda.sa.local_joincount.html │ ├── pygeoda.sa.local_moran.html │ ├── pygeoda.schc.html │ ├── pygeoda.skater.html │ ├── pygeoda.spatial_validation.html │ ├── pygeoda.standardize.html │ ├── pygeoda.stddev_breaks.html │ ├── pygeoda.total_sumofsquare.html │ ├── pygeoda.weights.Weight.html │ ├── pygeoda.weights.distance.html │ ├── pygeoda.weights.kernel.html │ ├── pygeoda.weights.knn.html │ ├── pygeoda.weights.queen.html │ ├── pygeoda.weights.rook.html │ └── pygeoda.within_sumofsquare.html ├── genindex.html ├── images │ ├── guerry1.png │ ├── guerry_g.png │ ├── guerry_geary.png │ ├── guerry_maxp.png │ ├── guerry_moran.png │ ├── guerry_moran_sig.png │ └── guerry_skater.png ├── index.html ├── install.html ├── intro.html ├── load_data.html ├── map_classification.html ├── objects.inv ├── py-modindex.html ├── search.html ├── searchindex.js ├── spatial_auto.html ├── spatial_clustering.html └── spatial_weights.html ├── docsrc ├── Makefile ├── make.bat └── source │ ├── api.rst │ ├── conf.py │ ├── esda_geopandas.rst │ ├── generated │ ├── pygeoda.Compactness.rst │ ├── pygeoda.Diameter.rst │ ├── pygeoda.Fragmentation.rst │ ├── pygeoda.JoinCountRatio.rst │ ├── pygeoda.ValidationResult.rst │ ├── pygeoda.Weight.rst │ ├── pygeoda.azp_greedy.rst │ ├── pygeoda.azp_sa.rst │ ├── pygeoda.azp_tabu.rst │ ├── pygeoda.batch_local_moran.rst │ ├── pygeoda.batchlisa.rst │ ├── pygeoda.demean.rst │ ├── pygeoda.distance_weights.rst │ ├── pygeoda.geoda.rst │ ├── pygeoda.hinge15_breaks.rst │ ├── pygeoda.hinge30_breaks.rst │ ├── pygeoda.kernel_knn_weights.rst │ ├── pygeoda.kernel_weights.rst │ ├── pygeoda.knn_weights.rst │ ├── pygeoda.lisa.rst │ ├── pygeoda.local_bijoincount.rst │ ├── pygeoda.local_bimoran.rst │ ├── pygeoda.local_g.rst │ ├── pygeoda.local_geary.rst │ ├── pygeoda.local_gstar.rst │ ├── pygeoda.local_joincount.rst │ ├── pygeoda.local_moran.rst │ ├── pygeoda.local_multigeary.rst │ ├── pygeoda.local_multijoincount.rst │ ├── pygeoda.local_multiquantilelisa.rst │ ├── pygeoda.local_quantilelisa.rst │ ├── pygeoda.mad.rst │ ├── pygeoda.make_spatial.rst │ ├── pygeoda.maxp_greedy.rst │ ├── pygeoda.maxp_sa.rst │ ├── pygeoda.maxp_tabu.rst │ ├── pygeoda.min_distthreshold.rst │ ├── pygeoda.natural_breaks.rst │ ├── pygeoda.neighbor_match_test.rst │ ├── pygeoda.open.rst │ ├── pygeoda.percentile_breaks.rst │ ├── pygeoda.quantile_breaks.rst │ ├── pygeoda.queen_weights.rst │ ├── pygeoda.redcap.rst │ ├── pygeoda.rook_weights.rst │ ├── pygeoda.schc.rst │ ├── pygeoda.skater.rst │ ├── pygeoda.spatial_validation.rst │ ├── pygeoda.standardize.rst │ └── pygeoda.stddev_breaks.rst │ ├── index.rst │ ├── install.rst │ ├── intro.rst │ ├── load_data.rst │ ├── map_classification.rst │ ├── spatial_auto.rst │ ├── spatial_clustering.rst │ └── spatial_weights.rst ├── libgeoda.i ├── pygeoda ├── __init__.py ├── classify │ ├── __init__.py │ └── breaks.py ├── clustering │ ├── __init__.py │ ├── azp.py │ ├── maxp.py │ ├── redcap.py │ ├── schc.py │ ├── skater.py │ ├── utils.py │ └── validation.py ├── data │ ├── __init__.py │ └── transform.py ├── gda.py ├── libgeoda.cpp ├── libgeoda.py ├── sa │ ├── __init__.py │ ├── geary.py │ ├── getisord.py │ ├── joincount.py │ ├── lisa.py │ ├── moran.py │ ├── neighbor_match_test.py │ └── quantile_lisa.py └── weights │ ├── __init__.py │ ├── distance.py │ ├── kernel.py │ ├── queen.py │ ├── rook.py │ └── weight.py ├── setup.py ├── swig.sh ├── test.sh └── tests ├── __init__.py ├── test_classify.py ├── test_clustering.py ├── test_data.py ├── test_lisa.py └── test_weights.py /.github/workflows/build-publish-mac.yml: -------------------------------------------------------------------------------- 1 | name: Mac builds 2 | 3 | on: [push, workflow_dispatch] 4 | 5 | jobs: 6 | build_and_publish: 7 | strategy: 8 | matrix: 9 | # macos-13 is an intel runner, macos-14+ is apple silicon 10 | os: [macos-13, macos-14, macos-15] 11 | 12 | runs-on: ${{ matrix.os }} 13 | 14 | permissions: 15 | id-token: write # IMPORTANT: this permission is mandatory for trusted publishing 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | submodules: recursive 21 | 22 | - name: Build Wheels 23 | uses: pypa/cibuildwheel@v2.22.0 24 | env: 25 | CXXFLAGS: -Wno-enum-constexpr-conversion 26 | CFLAGS: -Wno-enum-constexpr-conversion 27 | CIBW_BUILD: cp311-* cp312-* cp313-* 28 | CIBW_PROJECT_REQUIRES_PYTHON: '>=3.10' 29 | MACOSX_DEPLOYMENT_TARGET: 15.2 30 | 31 | - uses: actions/upload-artifact@v4 32 | with: 33 | name: pygeoda-${{ matrix.os }} 34 | path: wheelhouse/ 35 | 36 | - name: Publish to Pypi 37 | if: startsWith(github.ref, 'refs/tags/v') 38 | env: 39 | TWINE_USERNAME: __token__ 40 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 41 | run: | 42 | python3 -m venv venv 43 | source venv/bin/activate 44 | python3 -m pip install --upgrade --upgrade-strategy eager twine setuptools 45 | python3 -m twine upload wheelhouse/*.whl 46 | 47 | - name: Publish source to Pypi 48 | if: startsWith(github.ref, 'refs/tags/v') 49 | env: 50 | TWINE_USERNAME: __token__ 51 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 52 | run: | 53 | source venv/bin/activate 54 | python3 setup.py sdist 55 | python3 -m twine upload dist/*.tar.gz 56 | -------------------------------------------------------------------------------- /.github/workflows/build-publish-ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu builds 2 | 3 | on: [push, workflow_dispatch] 4 | 5 | jobs: 6 | build_and_publish: 7 | strategy: 8 | matrix: 9 | # macos-13 is an intel runner, macos-14+ is apple silicon 10 | os: [ubuntu-latest] 11 | 12 | runs-on: ${{ matrix.os }} 13 | 14 | permissions: 15 | id-token: write # IMPORTANT: this permission is mandatory for trusted publishing 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | submodules: recursive 21 | 22 | - name: Install dependencies on Ubuntu 23 | run: | 24 | sudo apt-get update 25 | sudo apt-get install -y build-essential libc6-dev 26 | 27 | - name: Build Wheels 28 | uses: pypa/cibuildwheel@v2.22.0 29 | env: 30 | CXXFLAGS: -Wno-enum-constexpr-conversion 31 | CFLAGS: -Wno-enum-constexpr-conversion 32 | CIBW_BUILD: cp311-* cp312-* cp313-* 33 | CIBW_PROJECT_REQUIRES_PYTHON: '>=3.10' 34 | 35 | - uses: actions/upload-artifact@v4 36 | with: 37 | name: pygeoda-${{ matrix.os }} 38 | path: wheelhouse/ 39 | 40 | - name: Publish to Pypi 41 | if: startsWith(github.ref, 'refs/tags/v') 42 | env: 43 | TWINE_USERNAME: __token__ 44 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 45 | run: | 46 | python3 -m venv venv 47 | source venv/bin/activate 48 | python3 -m pip install --upgrade --upgrade-strategy eager twine setuptools 49 | python3 -m twine upload wheelhouse/*.whl 50 | 51 | - name: Publish source to Pypi 52 | if: startsWith(github.ref, 'refs/tags/v') 53 | env: 54 | TWINE_USERNAME: __token__ 55 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 56 | run: | 57 | source venv/bin/activate 58 | python3 setup.py sdist 59 | python3 -m twine upload dist/*.tar.gz 60 | -------------------------------------------------------------------------------- /.github/workflows/win-build-publish.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Windows builds 4 | 5 | on: [push, workflow_dispatch] 6 | 7 | jobs: 8 | windows_build: 9 | runs-on: windows-latest 10 | 11 | strategy: 12 | matrix: 13 | msvc_arch: 14 | - amd64 15 | 16 | python_ver: 17 | - 3.11 18 | - 3.12 19 | - 3.13 20 | 21 | steps: 22 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 23 | - uses: actions/checkout@v4 24 | with: 25 | submodules: recursive 26 | 27 | - name: Setup MSVC toolset for Python 3.11 28 | uses: ilammy/msvc-dev-cmd@v1 29 | with: 30 | arch: ${{ matrix.msvc_arch }} 31 | toolset: 14.2 32 | 33 | - name: Setup Python Architecture x64 34 | uses: actions/setup-python@v5 35 | with: 36 | python-version: ${{ matrix.python_ver }} 37 | architecture: 'x64' 38 | 39 | - name: Build and Test 40 | shell: pwsh 41 | run: | 42 | python -m pip install --upgrade pip 43 | python -m pip install --upgrade virtualenv 44 | python -m virtualenv venv 45 | venv\\Scripts\\activate 46 | pip install --upgrade setuptools wheel virtualenv twine 47 | python setup.py build_ext --inplace 48 | python -m unittest 49 | 50 | - name: Build Wheels 51 | shell: pwsh 52 | run: | 53 | venv\\Scripts\\activate 54 | pip wheel -v -w wheelhouse --no-deps . 55 | dir wheelhouse/* 56 | 57 | - uses: actions/upload-artifact@v4 58 | with: 59 | name: pygeoda-${{ matrix.python_ver }}-${{ matrix.msvc_arch }}-win 60 | path: wheelhouse/ 61 | 62 | - name: Publish to Pypi 63 | if: startsWith(github.ref, 'refs/tags/v') 64 | # not on windows: pypa/gh-action-pypi-publish@release/v1 65 | env: 66 | TWINE_USERNAME: __token__ 67 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 68 | run: | 69 | venv\\Scripts\\activate 70 | python -m pip install --upgrade twine 71 | python -m twine upload wheelhouse/*.whl 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | *.so 4 | build/ 5 | dist/ 6 | pygeoda.egg-info/ 7 | .vscode/ 8 | libgeoda_local 9 | *.pyd 10 | *.DS_Store 11 | temp/ 12 | test.ipynb 13 | .ipynb_checkpoints/ 14 | Untitled.ipynb 15 | wheelhouse/ 16 | .venv/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "boost"] 2 | path = boost 3 | url = https://github.com/lixun910/pygeoda_boost 4 | [submodule "libgeoda"] 5 | path = libgeoda 6 | url = https://github.com/geodacenter/libgeoda 7 | -------------------------------------------------------------------------------- /Development.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Deployment 4 | 5 | 1. update libgeoda/ 6 | 2. ./swig.sh 7 | 3. add test cases in pygeoda 8 | 4. add modules in pygeoda 9 | 5. local dev and test 10 | 6. pr 11 | 12 | **deprecated** 13 | Pygeoda for windows is built using Appveyor (see: appveyor.yml) 14 | 15 | NOTE: 16 | 17 | python 3.5.0 msc 1900 visual c++ 2015 msvc14.0 (vs2015) 18 | (NOTE: python3.5 will not be supported on PyPi after 0.0.8-1) 19 | 20 | python 3.6.1 msc 1900 visual c++ 2015 (!!as conda-forge, msvc14.1 for py36) (vs2017) 21 | python 3.7.0 msc 1914 visual c++ 2017 msvc14.1 (vs2017) 22 | python 3.8.1 msc 1916 visual c++ 2017 msvc14.1 (vs2017) 23 | python 3.9.1 msc 1928 visual c++ 2019 msvc14.2 (vs2019) 24 | 25 | Pygeoda for Linux and Mac OSX is built using Travis (see .travis.yml) 26 | 27 | ## Sphinx Doc 28 | 29 | 1. use venv 30 | 2. pip install -U sphinx 31 | 3. pip install matplotlib 32 | 4. goto docsrc/ 33 | 5. make github 34 | 35 | ## conda-forge 36 | 37 | For conda-forge, the pygeoda PyPI package is used as the source. So, when 38 | updating pygeoda PyPI package, the conda-forge package should be 39 | automatically updated. 40 | 41 | 1. Fork conda-forge/staged-recipes 42 | 2. Create a new branch from the master branch 43 | 3. Add meta.yaml in the recipes/pygeoda/ directory 44 | 4. Submit a pull request (This will trigger testing on all operating systems) 45 | 5. Once merged, the package will be built and uploaded to conda-forge -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y git python3-pip python3-dev build-essential 5 | 6 | WORKDIR /tmp/pygeoda 7 | 8 | COPY . . 9 | 10 | RUN python3 setup.py install 11 | 12 | RUN python3 setup.py build_ext --inplace 13 | RUN python3 -m unittest -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include boost * 2 | recursive-include libgeoda * 3 | include LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pygeoda 2 | 3 | [![PyPI version](https://badge.fury.io/py/pygeoda.svg)](https://badge.fury.io/py/pygeoda) 4 | ![PyPI - Downloads](https://img.shields.io/pypi/dm/pygeoda) 5 | [![Anaconda-Server Badge](https://anaconda.org/conda-forge/pygeoda/badges/version.svg)](https://anaconda.org/conda-forge/pygeoda) 6 | [![Anaconda-Server Badge](https://anaconda.org/conda-forge/pygeoda/badges/downloads.svg)](https://anaconda.org/conda-forge/pygeoda) 7 | 8 | 9 | pygeoda is a python library for spatial data analysis based on libgeoda and GeoDa. It provides spatial data analysis functionalities including Exploratory Spatial Data Analysis, Spatial Cluster Detection and Clustering Analysis, Regionalization, etc. based on the C++ source code of GeoDa, which is an open-source software tool that serves as an introduction to spatial data analysis. 10 | 11 | ### Installation 12 | 13 | To install from PyPi: 14 | 15 | ``` 16 | pip install pygeoda 17 | ``` 18 | 19 | To install with conda run: 20 | 21 | ``` 22 | conda install -c conda-forge pygeoda 23 | ``` 24 | 25 | To install from source: (See more details: https://geodacenter.github.io/pygeoda/install.html) 26 | 27 | ``` 28 | pip install git+https://github.com/geodacenter/pygeoda 29 | ``` 30 | 31 | 32 | #### Documentation 33 | 34 | [https://geodacenter.github.io/pygeoda](https://geodacenter.github.io/pygeoda) 35 | 36 | #### Citation 37 | 38 | Anselin, L., Li, X. and Koschinsky, J. (2022), GeoDa, From the Desktop to an Ecosystem for Exploring Spatial Data. Geogr Anal, 54: 439-466. [Download Citation](https://onlinelibrary.wiley.com/action/showCitFormats?doi=10.1111%2Fgean.12311) 39 | 40 | 41 | #### Quick Start 42 | 43 | * pygeoda + ESRI Shapefile 44 | ```Python 45 | import pygeoda 46 | gda = pygeoda.open('./data/Guerry.shp') 47 | w = pygeoda.queen_weights(gda) 48 | lisa = pygeoda.local_moran(w, gda['Crm_prs']) 49 | #lisa object: 50 | # lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 51 | # lisa_pvalues(): [0.197, 0.013, ...] 52 | # lisa_num_nbrs(): [4, 6, ...] 53 | # lisa_clusters(): [0, 1, ...] 54 | # lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 55 | # lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 56 | ``` 57 | 58 | * pygeoda + GeoPandas 59 | 60 | ```Python 61 | import geopandas 62 | df = geopandas.read_file('./data/Guerry.shp') 63 | 64 | import pygeoda 65 | gda = pygeoda.open(df) 66 | w = pygeoda.queen_weights(gda) 67 | lisa = pygeoda.local_moran(w, gda['Crm_prs']) 68 | #lisa object: 69 | # lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 70 | # lisa_pvalues(): [0.197, 0.013, ...] 71 | # lisa_num_nbrs(): [4, 6, ...] 72 | # lisa_clusters(): [0, 1, ...] 73 | # lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 74 | # lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 75 | ``` 76 | 77 | 78 | ## Current version 0.1.0 79 | 80 | * Spatial Weights 81 | * Queen 82 | * Rook 83 | * Distance based 84 | * K-Nearest Neighbor 85 | * Kernel 86 | 87 | * Local Indicators of Spatial Association (LISA) 88 | * Local Moran 89 | * Local Geary 90 | * Local Getis-Ord 91 | * Local Join Count 92 | * Multivariate Local Geary 93 | * Local Join Count 94 | * Bivariate Local Join Count 95 | * (Multivariate) Colocation Local Join Count 96 | * Quantile LISA 97 | * Multivariate Quantile LISA 98 | 99 | * Spatial Clustering 100 | * SCHC Spatial Constrained Hierarchical Clustering 101 | * Single-linkage 102 | * Complete-linkage 103 | * Average-linkage 104 | * Ward-linkage 105 | * SKATER 106 | * REDCAP 107 | * First-order and Single-linkage 108 | * Full-order and Complete-linkage 109 | * Full-order and Average-linkage 110 | * Full-order and Single-linkage 111 | * Full-order and Ward-linkage 112 | * AZP 113 | * greedy 114 | * Tabu Search 115 | * Simulated Annealing 116 | * Max-p 117 | * greedy 118 | * Tabu Search 119 | * Simulated Annealing 120 | 121 | * Map Classification 122 | * NaturalBreaks 123 | * QuantileBreaks 124 | * Hinge15Breaks 125 | * Hinge30Breaks 126 | * PercentileBreaks 127 | * StddevBreaks 128 | 129 | * Data 130 | * Demean standardize 131 | * Standardize data (Z) 132 | * Median absolute deviation 133 | 134 | 135 | ## Authors 136 | 137 | Xun Li and Luc Anselin 138 | 139 | ## Contributors 140 | 141 | Guanpeng Dong; Yong Liu; Hang Zhang; Yeqing Han; 142 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | $PYTHON setup.py install -------------------------------------------------------------------------------- /data/Guerry.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/Guerry.dbf -------------------------------------------------------------------------------- /data/Guerry.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NTF_Paris_Lambert_zone_II",GEOGCS["GCS_NTF_Paris",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.33722917],UNIT["grad",0.01570796326794897]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",2200000],UNIT["Meter",1],PARAMETER["standard_parallel_1",52]] -------------------------------------------------------------------------------- /data/Guerry.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/Guerry.shp -------------------------------------------------------------------------------- /data/Guerry.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/Guerry.shx -------------------------------------------------------------------------------- /data/chicago_comm.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/chicago_comm.dbf -------------------------------------------------------------------------------- /data/chicago_comm.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["WGS84(DD)",DATUM["D_WGS84",SPHEROID["WGS84",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/chicago_comm.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/chicago_comm.shp -------------------------------------------------------------------------------- /data/chicago_comm.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/chicago_comm.shx -------------------------------------------------------------------------------- /data/columbus.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/columbus.dbf -------------------------------------------------------------------------------- /data/columbus.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/columbus.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/columbus.shp -------------------------------------------------------------------------------- /data/columbus.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/columbus.shx -------------------------------------------------------------------------------- /data/natregimes.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /data/natregimes.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/natregimes.shp -------------------------------------------------------------------------------- /data/natregimes.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/data/natregimes.shx -------------------------------------------------------------------------------- /docs/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: c751da21c461f4a565c82a6424ddecea 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/.nojekyll -------------------------------------------------------------------------------- /docs/_sources/api.rst.txt: -------------------------------------------------------------------------------- 1 | .. _api_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | pygeoda API reference 6 | ====================== 7 | 8 | pygeoda (I/O) 9 | ------------- 10 | 11 | .. autosummary:: 12 | :toctree: generated/ 13 | 14 | pygeoda.open 15 | pygeoda.geoda 16 | 17 | 18 | pygeoda.weights 19 | --------------- 20 | 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | pygeoda.Weight 25 | pygeoda.queen_weights 26 | pygeoda.rook_weights 27 | pygeoda.min_distthreshold 28 | pygeoda.distance_weights 29 | pygeoda.knn_weights 30 | pygeoda.kernel_weights 31 | pygeoda.kernel_knn_weights 32 | 33 | 34 | pygeoda (LISA) 35 | --------------------------------- 36 | 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | pygeoda.lisa 41 | pygeoda.local_moran 42 | pygeoda.local_bimoran 43 | pygeoda.local_geary 44 | pygeoda.local_multigeary 45 | pygeoda.local_joincount 46 | pygeoda.local_bijoincount 47 | pygeoda.local_multijoincount 48 | pygeoda.local_g 49 | pygeoda.local_gstar 50 | pygeoda.local_quantilelisa 51 | pygeoda.local_multiquantilelisa 52 | pygeoda.neighbor_match_test 53 | pygeoda.batchlisa 54 | pygeoda.batch_local_moran 55 | 56 | 57 | pygeoda (spatial clustering) 58 | ---------------------------- 59 | 60 | .. autosummary:: 61 | :toctree: generated/ 62 | 63 | pygeoda.skater 64 | pygeoda.redcap 65 | pygeoda.schc 66 | pygeoda.azp_greedy 67 | pygeoda.azp_sa 68 | pygeoda.azp_tabu 69 | pygeoda.maxp_greedy 70 | pygeoda.maxp_sa 71 | pygeoda.maxp_tabu 72 | pygeoda.spatial_validation 73 | pygeoda.Fragmentation 74 | pygeoda.Diameter 75 | pygeoda.Compactness 76 | pygeoda.JoinCountRatio 77 | pygeoda.ValidationResult 78 | pygeoda.make_spatial 79 | 80 | 81 | pygeoda (classify) 82 | ---------------------------- 83 | 84 | .. autosummary:: 85 | :toctree: generated/ 86 | 87 | pygeoda.hinge15_breaks 88 | pygeoda.hinge30_breaks 89 | pygeoda.natural_breaks 90 | pygeoda.quantile_breaks 91 | pygeoda.percentile_breaks 92 | pygeoda.stddev_breaks 93 | 94 | 95 | pygeoda (data) 96 | ---------------------------- 97 | 98 | .. autosummary:: 99 | :toctree: generated/ 100 | 101 | pygeoda.demean 102 | pygeoda.standardize 103 | pygeoda.mad -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.Compactness.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.Compactness 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Compactness 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Compactness.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.Diameter.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.Diameter 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Diameter 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Diameter.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.Fragmentation.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.Fragmentation 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Fragmentation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Fragmentation.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.JoinCountRatio.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.JoinCountRatio 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: JoinCountRatio 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~JoinCountRatio.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.PCA.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.PCA 2 | =========== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: PCA 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~PCA.__init__ 17 | ~PCA.getCumProp 18 | ~PCA.getEigenValues 19 | ~PCA.getKaiser 20 | ~PCA.getLoadings 21 | ~PCA.getMethod 22 | ~PCA.getPropOfVar 23 | ~PCA.getSqCorrelations 24 | ~PCA.getStandardDev 25 | ~PCA.getThresh95 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.ValidationResult.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.ValidationResult 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: ValidationResult 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~ValidationResult.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.Weight.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.Weight 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Weight 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Weight.__init__ 17 | ~Weight.get_neighbors 18 | ~Weight.has_isolates 19 | ~Weight.is_symmetric 20 | ~Weight.max_neighbors 21 | ~Weight.mean_neighbors 22 | ~Weight.median_neighbors 23 | ~Weight.min_neighbors 24 | ~Weight.save_weights 25 | ~Weight.spatial_lag 26 | ~Weight.weights_sparsity 27 | ~Weight.weights_type 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.azp_greedy.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_greedy 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_greedy -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.azp_sa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_sa 2 | =============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_sa -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.azp_tabu.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_tabu 2 | ================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_tabu -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.batch_local_moran.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.batch\_local\_moran 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: batch_local_moran -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.batchlisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.batchlisa 2 | ================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: batchlisa 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~batchlisa.__init__ 17 | ~batchlisa.lisa_bo 18 | ~batchlisa.lisa_clusters 19 | ~batchlisa.lisa_colors 20 | ~batchlisa.lisa_fdr 21 | ~batchlisa.lisa_labels 22 | ~batchlisa.lisa_num_nbrs 23 | ~batchlisa.lisa_pvalues 24 | ~batchlisa.lisa_values 25 | ~batchlisa.run 26 | ~batchlisa.set_permutations 27 | ~batchlisa.set_threads 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.between_sumofsquare.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.between\_sumofsquare 2 | ============================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: between_sumofsquare -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.clustering.maxp.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.clustering.maxp 2 | ======================= 3 | 4 | .. automodule:: pygeoda.clustering.maxp 5 | 6 | 7 | 8 | .. rubric:: Functions 9 | 10 | .. autosummary:: 11 | 12 | maxp 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.clustering.redcap.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.clustering.redcap 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda.clustering 5 | 6 | .. autofunction:: redcap -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.clustering.skater.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.clustering.skater 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda.clustering 5 | 6 | .. autofunction:: skater -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.demean.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.demean 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: demean -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.distance_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.distance\_weights 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: distance_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.geoda.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.geoda 2 | ============= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: geoda 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~geoda.GetFieldNames 17 | ~geoda.GetFieldTypes 18 | ~geoda.GetIntegerCol 19 | ~geoda.GetMapType 20 | ~geoda.GetNumCols 21 | ~geoda.GetNumObs 22 | ~geoda.GetRealCol 23 | ~geoda.GetStringCol 24 | ~geoda.GetUndefinedVals 25 | ~geoda.__init__ 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.geoda_to_geopandas.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.geoda\_to\_geopandas 2 | ============================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: geoda_to_geopandas -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.geopandas_to_geoda.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.geopandas\_to\_geoda 2 | ============================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: geopandas_to_geoda -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.hinge15_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.hinge15\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: hinge15_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.hinge30_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.hinge30\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: hinge30_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.kernel_knn_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.kernel\_knn\_weights 2 | ============================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: kernel_knn_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.kernel_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.kernel\_weights 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: kernel_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.knn_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.knn\_weights 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: knn_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.lisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.lisa 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: lisa 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~lisa.__init__ 17 | ~lisa.lisa_bo 18 | ~lisa.lisa_clusters 19 | ~lisa.lisa_colors 20 | ~lisa.lisa_fdr 21 | ~lisa.lisa_labels 22 | ~lisa.lisa_num_nbrs 23 | ~lisa.lisa_pvalues 24 | ~lisa.lisa_values 25 | ~lisa.run 26 | ~lisa.set_permutations 27 | ~lisa.set_threads 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_bijoincount.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_bijoincount 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_bijoincount -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_bimoran.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_bimoran 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_bimoran -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_g.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_g 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_g -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_geary.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_geary 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_geary -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_gstar.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_gstar 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_gstar -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_joincount.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_joincount 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_joincount -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_moran.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_moran 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_moran -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_multigeary.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multigeary 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multigeary -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_multijoincount.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multijoincount 2 | ============================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multijoincount -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_multiquantilelisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multiquantilelisa 2 | ================================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multiquantilelisa -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.local_quantilelisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.local\_quantilelisa 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_quantilelisa -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.mad.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.mad 2 | =========== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: mad -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.make_spatial.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.make\_spatial 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: make_spatial -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.maxp.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.maxp 2 | ============ 3 | 4 | .. automodule:: pygeoda.maxp 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | maxp_greedy 17 | maxp_sa 18 | maxp_tabu 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.maxp_greedy.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_greedy 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_greedy -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.maxp_sa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_sa 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_sa -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.maxp_tabu.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_tabu 2 | ================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_tabu -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.mds.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.mds 2 | =========== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: mds -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.min_distthreshold.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.min\_distthreshold 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: min_distthreshold -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.natural_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.natural\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: natural_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.neighbor_match_test.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.neighbor\_match\_test 2 | ============================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: neighbor_match_test -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.open.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.open 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: open -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.percentile_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.percentile\_breaks 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: percentile_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.quantile_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.quantile\_breaks 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: quantile_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.quantile_lisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.quantile\_lisa 2 | ====================== 3 | 4 | .. automodule:: pygeoda.quantile_lisa 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | local_multiquantilelisa 17 | local_quantilelisa 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.queen_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.queen\_weights 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: queen_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.redcap.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.redcap 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: redcap -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.rook_weights.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.rook\_weights 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: rook_weights -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.lisa.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.lisa 2 | =============== 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autoclass:: lisa 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~lisa.GetClusterIndicators 17 | ~lisa.GetColors 18 | ~lisa.GetLISAValues 19 | ~lisa.GetLabels 20 | ~lisa.GetNumNeighbors 21 | ~lisa.GetPValues 22 | ~lisa.Run 23 | ~lisa.SetPermutations 24 | ~lisa.SetThreads 25 | ~lisa.__init__ 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.local_g.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.local\_g 2 | =================== 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autofunction:: local_g -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.local_geary.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.local\_geary 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autofunction:: local_geary -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.local_gstar.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.local\_gstar 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autofunction:: local_gstar -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.local_joincount.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.local\_joincount 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autofunction:: local_joincount -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.sa.local_moran.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.sa.local\_moran 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda.sa 5 | 6 | .. autofunction:: local_moran -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.schc.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.schc 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: schc -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.skater.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.skater 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: skater -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.spatial_validation.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.spatial\_validation 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: spatial_validation -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.standardize.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.standardize 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: standardize -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.stddev_breaks.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.stddev\_breaks 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: stddev_breaks -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.total_sumofsquare.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.total\_sumofsquare 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: total_sumofsquare -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.Weight.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.Weight 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda.weights 5 | 6 | .. autoclass:: Weight 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Weight.GetNeighbors 17 | ~Weight.SaveToFile 18 | ~Weight.SpatialLag 19 | ~Weight.__init__ 20 | ~Weight.has_isolates 21 | ~Weight.is_symmetric 22 | ~Weight.max_neighbors 23 | ~Weight.mean_neighbors 24 | ~Weight.median_neighbors 25 | ~Weight.min_neighbors 26 | ~Weight.weights_sparsity 27 | ~Weight.weights_type 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.distance.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.distance 2 | ======================== 3 | 4 | .. automodule:: pygeoda.weights.distance 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | distance_weights 17 | knn_weights 18 | min_distthreshold 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.kernel.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.kernel 2 | ====================== 3 | 4 | .. automodule:: pygeoda.weights.kernel 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | kernel_knn_weights 17 | kernel_weights 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.knn.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.knn 2 | =================== 3 | 4 | .. currentmodule:: pygeoda.weights 5 | 6 | .. autofunction:: knn -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.queen.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.queen 2 | ===================== 3 | 4 | .. automodule:: pygeoda.weights.queen 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | queen_weights 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.weights.rook.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.weights.rook 2 | ==================== 3 | 4 | .. automodule:: pygeoda.weights.rook 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | .. rubric:: Functions 13 | 14 | .. autosummary:: 15 | 16 | rook_weights 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/_sources/generated/pygeoda.within_sumofsquare.rst.txt: -------------------------------------------------------------------------------- 1 | pygeoda.within\_sumofsquare 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: within_sumofsquare -------------------------------------------------------------------------------- /docs/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. pygeoda documentation master file, created by 2 | sphinx-quickstart on Thu Oct 3 19:20:18 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | pygeoda 0.0.8 7 | ============= 8 | 9 | pygeoda is a python library for spatial data analysis based on `GeoDa `_ 10 | and `libgeoda `_, It provides 11 | spatial data analysis functionalities including Exploratory Spatial Data Analysis, 12 | Spatial Cluster Detection and Clustering Analysis, Regionalization, etc. 13 | based on the C++ source code of GeoDa, which is an open-source software 14 | tool that serves as an introduction to spatial data analysis. 15 | 16 | 17 | Quick Start 18 | ----------- 19 | 20 | pygeoda is a light-weighted library and has no dependencies. 21 | It works with ESRI Shapefiles and `geopandas `_. 22 | 23 | >>> import pygeoda 24 | >>> gda = pygeoda.open('./data/Guerry.shp') 25 | >>> w = pygeoda.queen_weights(gda) 26 | Weights Meta-data: 27 | number of observations: 85 28 | is symmetric: True 29 | sparsity: 0.05813148788927336 30 | # min neighbors: 2 31 | # max neighbors: 8 32 | # mean neighbors: 4.9411764705882355 33 | # median neighbors: 5.0 34 | has isolates: False 35 | >>> lisa = pygeoda.local_moran(w, gda['Crm_prs']) 36 | >>> lisa 37 | lisa object: 38 | lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 39 | lisa_pvalues(): [0.197, 0.013, ...] 40 | lisa_num_nbrs(): [4, 6, ...] 41 | lisa_clusters(): [0, 1, ...] 42 | lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 43 | lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 44 | 45 | 46 | >>> import geopandas 47 | >>> df = geopandas.read_file('./data/Guerry.shp') 48 | >>> 49 | >>> import pygeoda 50 | >>> w = pygeoda.queen_weights(df) 51 | Weights Meta-data: 52 | number of observations: 85 53 | is symmetric: True 54 | sparsity: 0.05813148788927336 55 | # min neighbors: 2 56 | # max neighbors: 8 57 | # mean neighbors: 4.9411764705882355 58 | # median neighbors: 5.0 59 | has isolates: False 60 | >>> lisa = pygeoda.local_moran(w, df['Crm_prs']) 61 | >>> lisa 62 | lisa object: 63 | lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 64 | lisa_pvalues(): [0.197, 0.013, ...] 65 | lisa_num_nbrs(): [4, 6, ...] 66 | lisa_clusters(): [0, 1, ...] 67 | lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 68 | lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 69 | 70 | .. toctree:: 71 | :maxdepth: 2 72 | :caption: USER GUIDE 73 | 74 | 1. Introduction 75 | 2. Installation 76 | 3. Load Spatial Data 77 | 4. Map Classification 78 | 5. Spatial Weights 79 | 6. Local Indicators of Spatial Association 80 | 7. Spatial Clustering 81 | ESDA with pygeoda and geopandas 82 | 83 | 84 | 85 | ------------- 86 | 87 | .. toctree:: 88 | :maxdepth: 2 89 | :caption: API REFERENCE 90 | 91 | pygeoda API 92 | 93 | 94 | 95 | Indices and tables 96 | ================== 97 | 98 | * :ref:`genindex` 99 | * :ref:`modindex` 100 | * :ref:`search` 101 | 102 | Authors 103 | ======= 104 | 105 | `Xun Li `_; `Luc Anselin `_ 106 | 107 | Contributors 108 | ============ 109 | 110 | `Guanpeng Dong `_; `Yong Liu `_; Hang Zhang; Yeqing Han; 111 | 112 | ---- 113 | 114 | .. image:: https://spatial.uchicago.edu/sites/spatial.uchicago.edu/files/styles/columnwidth-wider/public/uploads/images/CSDS_logo_4C_1.jpg?itok=rKJfXzmf 115 | :target: https://spatial.uchicago.edu 116 | :alt: CSDS is an initiative of the Division of Social Sciences and part of the UChicago's investment in computational social science. -------------------------------------------------------------------------------- /docs/_sources/install.rst.txt: -------------------------------------------------------------------------------- 1 | .. _install_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 2 Installation 6 | ============== 7 | 8 | Like GeoDa desktop software, pygeoda are avaiable to 9 | different platforms including Mac, Linux, and Windows. 10 | You can install pygeoda using pip: 11 | :: 12 | 13 | pip install pygeoda 14 | 15 | 16 | To install pygeoda from source: 17 | 18 | 2.1 Windows 19 | ----------- 20 | 21 | For Windows users, Microsoft Visual C++ needs to be installed first. 22 | Please see https://wiki.python.org/moin/WindowsCompilers to find which Visual 23 | C++ compiler to use with a specific python version. 24 | 25 | Install pygeoda from source using pip: 26 | :: 27 | 28 | pip install git+https://github.com/GeoDaCenter/pygeoda 29 | 30 | 2.2 Linux 31 | --------- 32 | 33 | For Linux users, the “Build Essential Tools” needs to be installed first: 34 | :: 35 | 36 | sudo apt-get update 37 | sudo apt-get install build-essential 38 | 39 | Install pygeoda from source using pip: 40 | :: 41 | 42 | pip install git+https://github.com/GeoDaCenter/pygeoda 43 | 44 | 2.3 Mac 45 | ------- 46 | 47 | For Mac users, the “Xcode Command Line Tools” needs to be 48 | installed for installing pygeoda from source. 49 | It is a free software provided by Apple, which can be installed 50 | by using the following command in a terminal: 51 | :: 52 | 53 | xcode-select --install 54 | 55 | Install pygeoda from source using pip: 56 | :: 57 | 58 | pip install git+https://github.com/GeoDaCenter/pygeoda 59 | 60 | 2.4 Import pygeoda 61 | ------------------ 62 | 63 | If everything installed without error, you should be able to import pygeoda in Python: 64 | :: 65 | 66 | import pygeoda 67 | -------------------------------------------------------------------------------- /docs/_sources/intro.rst.txt: -------------------------------------------------------------------------------- 1 | .. _api_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 1. Introduction to pygeoda 6 | ========================== 7 | 8 | pygeoda is a python library for spatial data analysis based on libgeoda, 9 | which is a non-UI and API-based C++ library. It is designed for programmers to 10 | do spatial data analysis using their favorite programming languages 11 | (R, Python, Javascript, etc.). It also aims to be easily integrated with other 12 | libraries, software, or systems on different platforms. 13 | 14 | 15 | 1.1 Open Resources 16 | ------------------ 17 | 18 | * The pygeoda is open-sourced at: https://github.com/GeoDaCenter/pygeoda. 19 | 20 | If you prefer programming in R, you can try **rgeoda** for spatial data analysis: 21 | 22 | * The rgeoda is open-sourced at: https://github.com/GeoDaCenter/rgeoda. 23 | 24 | If you have any questions or issues, please open a ticket in one of the above repositories. 25 | 26 | .. note:: 27 | Since pygeoda is under active development, this document will be updated frequently. Please "watch" this github repository to get notifications. -------------------------------------------------------------------------------- /docs/_sources/load_data.rst.txt: -------------------------------------------------------------------------------- 1 | .. _load_data_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 3 Load Spatial Data 6 | =================== 7 | 8 | pygeoda supports reading the ESRI ShapeFiles. For other data formats, 9 | please use `geopandas `_ to load the spatial data first, 10 | then pass the geopandas object to function `pygeoda.open()`. 11 | 12 | For example, to load the ESRI Shapefile **Guerry.shp** 13 | download from: https://geodacenter.github.io/data-and-lab/Guerry/. 14 | 15 | :: 16 | 17 | >>> import pygeoda 18 | >>> guerry = pygeoda.open("./data/Guerry.shp") 19 | >>> guerry 20 | geoda object: 21 | Number of observations: 85 22 | Number of fields: 27 23 | Geometry type(s): Polygon 24 | field name: field type (shapfile): 25 | CODE_DE string 26 | COUNT real 27 | AVE_ID_ real 28 | ... 29 | 30 | The geopandas can be used to load or manipulate spatial data first. 31 | Then, the geopandas object can be used to create a geoda object using 32 | the same function `pygeoda.open()`: 33 | 34 | :: 35 | 36 | >>> import geopandas 37 | >>> df = geopandas.read_file("./data/Guerry.shp") 38 | >>> 39 | >>> import pygeoda 40 | >>> guerry = pygeoda.open(df) 41 | >>> guerry 42 | geoda object: 43 | Number of observations: 85 44 | Number of fields: 27 45 | Geometry type(s): ('MultiPolygon', 'Polygon') 46 | field name: field type (numpy.dtype): 47 | CODE_DE object 48 | COUNT float64 49 | AVE_ID_ float64 50 | ... 51 | 52 | .. note:: 53 | The "Geometry type(s)" and "field type" are different from using 54 | pygeoda.open() function to open an ESRI shapefile and a geopandas object. 55 | When opening an ESRI shapefile, the "Geometry type" could be one of 56 | {'Polygon', 'Point', 'Line'} and the "field type" could be one of 57 | {'real', 'string', 'integer'}. When opening a geopandas object, the 58 | "Geometry type" is the defined by `GeoSeries `_ 59 | (e.g. MultiPolygon, Polygon, etc.) and the "field type" is defined by `numpy.dtype` 60 | (e.g. object, float64, int64, etc.) 61 | 62 | 63 | 3.1 Attributes of geoda object 64 | ------------------------------ 65 | 66 | * n_cols 67 | * n_obs 68 | * field_names 69 | * field_types 70 | 71 | To access the meta-data of the loaded Guerry dataset: 72 | :: 73 | 74 | >>> print("number of columns:", guerry.num_cols) 75 | number of columns: 26 76 | 77 | >>> print("number of observations:", guerry.num_obs) 78 | number of observations: 85 79 | 80 | >>> print("field names:", guerry.field_names) 81 | field names: ('CODE_DE', 'COUNT', 'AVE_ID_', 'dept', 'Region', 'Dprtmnt', 'Crm_prs', 'Crm_prp', 'Litercy', 'Donatns', 'Infants', 'Suicids', 'MainCty', 'Wealth', 'Commerc', 'Clergy', 'Crm_prn', 'Infntcd', 'Dntn_cl', 'Lottery', 'Desertn', 'Instrct', 'Prsttts', 'Distanc', 'Area', 'Pop1831') 82 | 83 | >>> print("field types:", guerry.field_types) 84 | field types: {'CODE_DE': 'string', 'COUNT':'real', 'AVE_ID_': 'real',...} 85 | 86 | .. note:: 87 | If using geopandas object in `pygeoda.open()`, there will be a geometry column "geometry" with data type "geometry". 88 | 89 | 3.2 Access Table Data 90 | --------------------- 91 | 92 | One can use the bracket `[ ]` operator to access the table data: 93 | 94 | >>> guerry = pygeoda.open('./data/Guerry.shp') 95 | >>> guerry['Crm_prs'] 96 | (28870.0, 26226.0, 26747.0, 12935.0,...) 97 | >>> guerry[['Crm_prs', 'Litercy']] 98 | [(28870.0, 26226.0, 26747.0, 12935.0,...), (37.0, 51.0, 13.0,...)] 99 | 100 | 101 | .. note:: 102 | If using geopandas object in `pygeoda.open()`, there output of `[[ ]]` operator is a dataframe object, which can be 103 | used as an input parameter in pygeoda functions like `skater()`, `neighbor_match_test()`, etc. 104 | 105 | :: 106 | 107 | >>> guerry = pygeoda.open(df) 108 | >>> guerry['Crm_prs'] 109 | [28870.0, 26226.0, 26747.0, 12935.0,...] 110 | >>> guerry[['Crm_prs', 'Litercy']] 111 | Crm_prs Litercy 112 | -------------------- 113 | 0 28880 37 114 | 1 26226 51 115 | 116 | 117 | .. note:: 118 | In pygeoda, to pass the values of a single variable to a pygeoda function, one can use either a tuple or list; 119 | to pass the values of multiple variables, one can use either a list of tuples/lists or a `dataframe `_. -------------------------------------------------------------------------------- /docs/_sources/map_classification.rst.txt: -------------------------------------------------------------------------------- 1 | .. _map_classification_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 4 Map Classification 6 | ==================== 7 | 8 | pygeoda provids following methods for univariate map classification: 9 | 10 | * Hinge box breaks: hinge15_breaks() and hinge30_breaks() 11 | * Natural breaks: natural_breaks() 12 | * Quantile breaks: quantile_breaks() 13 | * Percentile breaks: percentile_breaks() 14 | * Standard deviation breaks: stddev_breaks() 15 | 16 | These methods of map classification calculate a corresponding breakpoint 17 | list for a selected variable. For more information about the map classification, please read Dr. Luc Anselin's lab note: 18 | http://geodacenter.github.io/workbook/6a_local_auto/lab6a.html. 19 | 20 | 21 | 4.1 Hinge Box Breaks 22 | -------------------- 23 | 24 | Hinge Box Breaks calculates a list of breakpoints, including the top, bottom, median, 25 | and two quartiles of the data. Here the hinge can be 1.5 or 3.0. For example, we can 26 | call function `hinge15_breaks()` or `hinge30_breaks` with the data "Crm_prp" as input 27 | parameter: 28 | :: 29 | 30 | >>> breaks15 = pygeoda.hinge15_breaks(guerry['Crm_prp']) 31 | >>> print(breaks15) 32 | (1190.0, 5990.0, 7624.0, 9190.0, 13990.0) 33 | 34 | >>> breaks30 = pygeoda.hinge30_breaks(guerry['Crm_prp']) 35 | >>> print(breaks30) 36 | (-3610.0, 5990.0, 7624.0, 9190.0, 18790.0) 37 | 38 | 39 | 4.2 Natural Breaks 40 | ------------------ 41 | 42 | Natural Breaks calculates a list of breakpoints based on the fracture principle of 43 | maximum similarity within a group. For example, we can call function `natural_breaks()` 44 | with the data "Crm_prp" and the number of classification “k” as input parameters: 45 | :: 46 | 47 | >>> breaks = pygeoda.natural_breaks(5, guerry['Crm_prp']) 48 | >>> print(breaks) 49 | (5521.0, 7204.0, 10237.0, 15890.0) 50 | 51 | 52 | 4.3 Quantile Breaks 53 | ------------------- 54 | 55 | Quantile Breaks is based on sorted values for a variable that are then grouped 56 | into bins that each have the same number of observations, the so-called quantiles. 57 | For example, we can call function `quantile_breaks()` with the data "Crm_prp", 58 | and the number of classification “k” as input parameters: 59 | :: 60 | 61 | >>> breaks = pygeoda.quantile_breaks(5, guerry['Crm_prp']) 62 | >>> print(breaks) 63 | (5439.0, 6886.0, 8205.0, 9584.5) 64 | 65 | 66 | 4.4 Percentile Breaks 67 | --------------------- 68 | 69 | Percentile Breaks divides the data into six ranges: the lowest 1%, 1-10%, 10-50%, 70 | 50-90%, 90-99% and the top 1%. It returns the range boundaries as a breakpoint list. 71 | For example, we can call function `natural_breaks()` with the data "Crm_prp" as 72 | input parameter: 73 | :: 74 | 75 | >>> breaks = pygeoda.percentile_breaks(guerry['Crm_prp']) 76 | >>> print(breaks) 77 | (1906.3, 4529.0, 7624.0, 10954.0, 19467.8) 78 | 79 | 80 | 4.5 Standard Deviation Breaks 81 | ----------------------------- 82 | 83 | Standard Deviation Breaks calculates the number of standard deviational units of the 84 | range from lowest to highest, returning a breakpoint list. For example, we can 85 | call function `stddev_breaks()` with the data "Crm_prp" as input parameter: 86 | :: 87 | 88 | >>> breaks = pygeoda.stddev_breaks(guerry['Crm_prp']) 89 | >>> print(breaks) 90 | (1784.1106064421238, 4832.725891456355, 7881.341176470588, 10929.95646148482, 13978.571746499052) 91 | 92 | -------------------------------------------------------------------------------- /docs/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/Roboto-Slab-Bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/Roboto-Slab-Regular.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-bold-italic.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-bold-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-normal-italic.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-normal-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-normal.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/css/fonts/lato-normal.woff2 -------------------------------------------------------------------------------- /docs/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.0.8', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false 12 | }; -------------------------------------------------------------------------------- /docs/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/file.png -------------------------------------------------------------------------------- /docs/_static/fonts/Inconsolata-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Inconsolata-Bold.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Inconsolata.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Inconsolata.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bold.eot -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bold.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bold.woff -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bolditalic.eot -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bolditalic.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bolditalic.woff -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-bolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-bolditalic.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-italic.eot -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-italic.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-italic.woff -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-regular.eot -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-regular.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-regular.woff -------------------------------------------------------------------------------- /docs/_static/fonts/Lato/lato-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/Lato/lato-regular.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab-Bold.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab-Regular.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff -------------------------------------------------------------------------------- /docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 -------------------------------------------------------------------------------- /docs/_static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/_static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/_static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/_static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/docs/_static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/_static/js/badge_only.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}}); -------------------------------------------------------------------------------- /docs/_static/js/html5shiv-printshiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /docs/_static/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /docs/_static/js/theme.js: -------------------------------------------------------------------------------- 1 | !function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}t.length>0&&($(".wy-menu-vertical .current").removeClass("current"),t.addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l1").parent().addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l2").addClass("current"),t.closest("li.toctree-l3").addClass("current"),t.closest("li.toctree-l4").addClass("current"),t.closest("li.toctree-l5").addClass("current"),t[0].scrollIntoView())}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;tNUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docsrc/source/api.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | pygeoda API reference 6 | ====================== 7 | 8 | pygeoda (I/O) 9 | ------------- 10 | 11 | .. autosummary:: 12 | :toctree: generated/ 13 | 14 | pygeoda.open 15 | pygeoda.geoda 16 | 17 | 18 | pygeoda.weights 19 | --------------- 20 | 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | pygeoda.Weight 25 | pygeoda.queen_weights 26 | pygeoda.rook_weights 27 | pygeoda.min_distthreshold 28 | pygeoda.distance_weights 29 | pygeoda.knn_weights 30 | pygeoda.kernel_weights 31 | pygeoda.kernel_knn_weights 32 | 33 | 34 | pygeoda (LISA) 35 | --------------------------------- 36 | 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | pygeoda.lisa 41 | pygeoda.local_moran 42 | pygeoda.local_bimoran 43 | pygeoda.local_geary 44 | pygeoda.local_multigeary 45 | pygeoda.local_joincount 46 | pygeoda.local_bijoincount 47 | pygeoda.local_multijoincount 48 | pygeoda.local_g 49 | pygeoda.local_gstar 50 | pygeoda.local_quantilelisa 51 | pygeoda.local_multiquantilelisa 52 | pygeoda.neighbor_match_test 53 | pygeoda.batchlisa 54 | pygeoda.batch_local_moran 55 | 56 | 57 | pygeoda (spatial clustering) 58 | ---------------------------- 59 | 60 | .. autosummary:: 61 | :toctree: generated/ 62 | 63 | pygeoda.skater 64 | pygeoda.redcap 65 | pygeoda.schc 66 | pygeoda.azp_greedy 67 | pygeoda.azp_sa 68 | pygeoda.azp_tabu 69 | pygeoda.maxp_greedy 70 | pygeoda.maxp_sa 71 | pygeoda.maxp_tabu 72 | pygeoda.spatial_validation 73 | pygeoda.Fragmentation 74 | pygeoda.Diameter 75 | pygeoda.Compactness 76 | pygeoda.JoinCountRatio 77 | pygeoda.ValidationResult 78 | pygeoda.make_spatial 79 | 80 | 81 | pygeoda (classify) 82 | ---------------------------- 83 | 84 | .. autosummary:: 85 | :toctree: generated/ 86 | 87 | pygeoda.hinge15_breaks 88 | pygeoda.hinge30_breaks 89 | pygeoda.natural_breaks 90 | pygeoda.quantile_breaks 91 | pygeoda.percentile_breaks 92 | pygeoda.stddev_breaks 93 | 94 | 95 | pygeoda (data) 96 | ---------------------------- 97 | 98 | .. autosummary:: 99 | :toctree: generated/ 100 | 101 | pygeoda.demean 102 | pygeoda.standardize 103 | pygeoda.mad -------------------------------------------------------------------------------- /docsrc/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | import os 14 | import sys 15 | sys.path.insert(0, os.path.abspath('../../')) 16 | print(sys.path) 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'pygeoda' 21 | copyright = '2019, Xun Li; Luc Anselin.' 22 | author = 'Xun Li; Luc Anselin' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '0.0.8' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = ['sphinx.ext.autodoc', 34 | 'sphinx.ext.autosummary', 35 | 'sphinx.ext.viewcode', 36 | 'sphinx.ext.mathjax', 37 | 'sphinx.ext.doctest', 38 | 'sphinx.ext.intersphinx', 39 | 'matplotlib.sphinxext.plot_directive', 40 | 'sphinx.ext.napoleon'] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # List of patterns, relative to source directory, that match files and 46 | # directories to ignore when looking for source files. 47 | # This pattern also affects html_static_path and html_extra_path. 48 | exclude_patterns = [] 49 | 50 | 51 | # -- Options for HTML output ------------------------------------------------- 52 | 53 | # The theme to use for HTML and HTML Help pages. See the documentation for 54 | # a list of builtin themes. 55 | # 56 | html_theme = "sphinx_rtd_theme" 57 | 58 | # Add any paths that contain custom static files (such as style sheets) here, 59 | # relative to this directory. They are copied after the builtin static files, 60 | # so a file named "default.css" will overwrite the builtin "default.css". 61 | html_static_path = ['static'] 62 | 63 | html_theme_options = { 64 | 'canonical_url': 'https://geodacenter.github.io/pygeoda', 65 | 'analytics_id': 'UA-182260526-2', # Provided by Google in your dashboard 66 | 'logo_only': False, 67 | 'display_version': True, 68 | 'prev_next_buttons_location': 'bottom', 69 | 'style_external_links': False, 70 | 'style_nav_header_background': '#343131', 71 | # Toc options 72 | 'collapse_navigation': False, 73 | 'sticky_navigation': True, 74 | 'navigation_depth': 4, 75 | 'includehidden': True, 76 | 'titles_only': False 77 | } 78 | 79 | autosummary_generate = True 80 | 81 | # Napoleon settings 82 | napoleon_google_docstring = True -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.Compactness.rst: -------------------------------------------------------------------------------- 1 | pygeoda.Compactness 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Compactness 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Compactness.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.Diameter.rst: -------------------------------------------------------------------------------- 1 | pygeoda.Diameter 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Diameter 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Diameter.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.Fragmentation.rst: -------------------------------------------------------------------------------- 1 | pygeoda.Fragmentation 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Fragmentation 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Fragmentation.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.JoinCountRatio.rst: -------------------------------------------------------------------------------- 1 | pygeoda.JoinCountRatio 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: JoinCountRatio 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~JoinCountRatio.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.ValidationResult.rst: -------------------------------------------------------------------------------- 1 | pygeoda.ValidationResult 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: ValidationResult 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~ValidationResult.__init__ 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.Weight.rst: -------------------------------------------------------------------------------- 1 | pygeoda.Weight 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: Weight 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~Weight.__init__ 17 | ~Weight.get_neighbors 18 | ~Weight.has_isolates 19 | ~Weight.is_symmetric 20 | ~Weight.max_neighbors 21 | ~Weight.mean_neighbors 22 | ~Weight.median_neighbors 23 | ~Weight.min_neighbors 24 | ~Weight.save_weights 25 | ~Weight.spatial_lag 26 | ~Weight.weights_sparsity 27 | ~Weight.weights_type 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.azp_greedy.rst: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_greedy 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_greedy -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.azp_sa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_sa 2 | =============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_sa -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.azp_tabu.rst: -------------------------------------------------------------------------------- 1 | pygeoda.azp\_tabu 2 | ================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: azp_tabu -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.batch_local_moran.rst: -------------------------------------------------------------------------------- 1 | pygeoda.batch\_local\_moran 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: batch_local_moran -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.batchlisa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.batchlisa 2 | ================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: batchlisa 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~batchlisa.__init__ 17 | ~batchlisa.lisa_bo 18 | ~batchlisa.lisa_clusters 19 | ~batchlisa.lisa_colors 20 | ~batchlisa.lisa_fdr 21 | ~batchlisa.lisa_labels 22 | ~batchlisa.lisa_num_nbrs 23 | ~batchlisa.lisa_pvalues 24 | ~batchlisa.lisa_values 25 | ~batchlisa.run 26 | ~batchlisa.set_permutations 27 | ~batchlisa.set_threads 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.demean.rst: -------------------------------------------------------------------------------- 1 | pygeoda.demean 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: demean -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.distance_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.distance\_weights 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: distance_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.geoda.rst: -------------------------------------------------------------------------------- 1 | pygeoda.geoda 2 | ============= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: geoda 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~geoda.GetFieldNames 17 | ~geoda.GetFieldTypes 18 | ~geoda.GetIntegerCol 19 | ~geoda.GetMapType 20 | ~geoda.GetNumCols 21 | ~geoda.GetNumObs 22 | ~geoda.GetRealCol 23 | ~geoda.GetStringCol 24 | ~geoda.GetUndefinedVals 25 | ~geoda.__init__ 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.hinge15_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.hinge15\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: hinge15_breaks -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.hinge30_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.hinge30\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: hinge30_breaks -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.kernel_knn_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.kernel\_knn\_weights 2 | ============================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: kernel_knn_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.kernel_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.kernel\_weights 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: kernel_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.knn_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.knn\_weights 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: knn_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.lisa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.lisa 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autoclass:: lisa 7 | 8 | 9 | .. automethod:: __init__ 10 | 11 | 12 | .. rubric:: Methods 13 | 14 | .. autosummary:: 15 | 16 | ~lisa.__init__ 17 | ~lisa.lisa_bo 18 | ~lisa.lisa_clusters 19 | ~lisa.lisa_colors 20 | ~lisa.lisa_fdr 21 | ~lisa.lisa_labels 22 | ~lisa.lisa_num_nbrs 23 | ~lisa.lisa_pvalues 24 | ~lisa.lisa_values 25 | ~lisa.run 26 | ~lisa.set_permutations 27 | ~lisa.set_threads 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_bijoincount.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_bijoincount 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_bijoincount -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_bimoran.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_bimoran 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_bimoran -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_g.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_g 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_g -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_geary.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_geary 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_geary -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_gstar.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_gstar 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_gstar -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_joincount.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_joincount 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_joincount -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_moran.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_moran 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_moran -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_multigeary.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multigeary 2 | ========================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multigeary -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_multijoincount.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multijoincount 2 | ============================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multijoincount -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_multiquantilelisa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_multiquantilelisa 2 | ================================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_multiquantilelisa -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.local_quantilelisa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.local\_quantilelisa 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: local_quantilelisa -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.mad.rst: -------------------------------------------------------------------------------- 1 | pygeoda.mad 2 | =========== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: mad -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.make_spatial.rst: -------------------------------------------------------------------------------- 1 | pygeoda.make\_spatial 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: make_spatial -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.maxp_greedy.rst: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_greedy 2 | ==================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_greedy -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.maxp_sa.rst: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_sa 2 | ================ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_sa -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.maxp_tabu.rst: -------------------------------------------------------------------------------- 1 | pygeoda.maxp\_tabu 2 | ================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: maxp_tabu -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.min_distthreshold.rst: -------------------------------------------------------------------------------- 1 | pygeoda.min\_distthreshold 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: min_distthreshold -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.natural_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.natural\_breaks 2 | ======================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: natural_breaks -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.neighbor_match_test.rst: -------------------------------------------------------------------------------- 1 | pygeoda.neighbor\_match\_test 2 | ============================= 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: neighbor_match_test -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.open.rst: -------------------------------------------------------------------------------- 1 | pygeoda.open 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: open -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.percentile_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.percentile\_breaks 2 | ========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: percentile_breaks -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.quantile_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.quantile\_breaks 2 | ======================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: quantile_breaks -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.queen_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.queen\_weights 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: queen_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.redcap.rst: -------------------------------------------------------------------------------- 1 | pygeoda.redcap 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: redcap -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.rook_weights.rst: -------------------------------------------------------------------------------- 1 | pygeoda.rook\_weights 2 | ===================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: rook_weights -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.schc.rst: -------------------------------------------------------------------------------- 1 | pygeoda.schc 2 | ============ 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: schc -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.skater.rst: -------------------------------------------------------------------------------- 1 | pygeoda.skater 2 | ============== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: skater -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.spatial_validation.rst: -------------------------------------------------------------------------------- 1 | pygeoda.spatial\_validation 2 | =========================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: spatial_validation -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.standardize.rst: -------------------------------------------------------------------------------- 1 | pygeoda.standardize 2 | =================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: standardize -------------------------------------------------------------------------------- /docsrc/source/generated/pygeoda.stddev_breaks.rst: -------------------------------------------------------------------------------- 1 | pygeoda.stddev\_breaks 2 | ====================== 3 | 4 | .. currentmodule:: pygeoda 5 | 6 | .. autofunction:: stddev_breaks -------------------------------------------------------------------------------- /docsrc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. pygeoda documentation master file, created by 2 | sphinx-quickstart on Thu Oct 3 19:20:18 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | pygeoda 0.0.8 7 | ============= 8 | 9 | pygeoda is a python library for spatial data analysis based on `GeoDa `_ 10 | and `libgeoda `_, It provides 11 | spatial data analysis functionalities including Exploratory Spatial Data Analysis, 12 | Spatial Cluster Detection and Clustering Analysis, Regionalization, etc. 13 | based on the C++ source code of GeoDa, which is an open-source software 14 | tool that serves as an introduction to spatial data analysis. 15 | 16 | 17 | Quick Start 18 | ----------- 19 | 20 | pygeoda is a light-weighted library and has no dependencies. 21 | It works with ESRI Shapefiles and `geopandas `_. 22 | 23 | >>> import pygeoda 24 | >>> gda = pygeoda.open('./data/Guerry.shp') 25 | >>> w = pygeoda.queen_weights(gda) 26 | Weights Meta-data: 27 | number of observations: 85 28 | is symmetric: True 29 | sparsity: 0.05813148788927336 30 | # min neighbors: 2 31 | # max neighbors: 8 32 | # mean neighbors: 4.9411764705882355 33 | # median neighbors: 5.0 34 | has isolates: False 35 | >>> lisa = pygeoda.local_moran(w, gda['Crm_prs']) 36 | >>> lisa 37 | lisa object: 38 | lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 39 | lisa_pvalues(): [0.197, 0.013, ...] 40 | lisa_num_nbrs(): [4, 6, ...] 41 | lisa_clusters(): [0, 1, ...] 42 | lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 43 | lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 44 | 45 | 46 | >>> import geopandas 47 | >>> df = geopandas.read_file('./data/Guerry.shp') 48 | >>> 49 | >>> import pygeoda 50 | >>> w = pygeoda.queen_weights(df) 51 | Weights Meta-data: 52 | number of observations: 85 53 | is symmetric: True 54 | sparsity: 0.05813148788927336 55 | # min neighbors: 2 56 | # max neighbors: 8 57 | # mean neighbors: 4.9411764705882355 58 | # median neighbors: 5.0 59 | has isolates: False 60 | >>> lisa = pygeoda.local_moran(w, df['Crm_prs']) 61 | >>> lisa 62 | lisa object: 63 | lisa_values(): [0.516120231288079, 0.8182751384950308, ...] 64 | lisa_pvalues(): [0.197, 0.013, ...] 65 | lisa_num_nbrs(): [4, 6, ...] 66 | lisa_clusters(): [0, 1, ...] 67 | lisa_labels(): ('Not significant', 'High-High', 'Low-Low', 'High-Low', 'Low-High', 'Undefined', 'Isolated') 68 | lisa_colors(): ('#eeeeee', '#FF0000', '#0000FF', '#a7adf9', '#f4ada8', '#464646', '#999999') 69 | 70 | .. toctree:: 71 | :maxdepth: 2 72 | :caption: USER GUIDE 73 | 74 | 1. Introduction 75 | 2. Installation 76 | 3. Load Spatial Data 77 | 4. Map Classification 78 | 5. Spatial Weights 79 | 6. Local Indicators of Spatial Association 80 | 7. Spatial Clustering 81 | ESDA with pygeoda and geopandas 82 | 83 | 84 | 85 | ------------- 86 | 87 | .. toctree:: 88 | :maxdepth: 2 89 | :caption: API REFERENCE 90 | 91 | pygeoda API 92 | 93 | 94 | 95 | Indices and tables 96 | ================== 97 | 98 | * :ref:`genindex` 99 | * :ref:`modindex` 100 | * :ref:`search` 101 | 102 | Authors 103 | ======= 104 | 105 | `Xun Li `_; `Luc Anselin `_ 106 | 107 | Contributors 108 | ============ 109 | 110 | `Guanpeng Dong `_; `Yong Liu `_; Hang Zhang; Yeqing Han; 111 | 112 | ---- 113 | 114 | .. image:: https://spatial.uchicago.edu/sites/spatial.uchicago.edu/files/styles/columnwidth-wider/public/uploads/images/CSDS_logo_4C_1.jpg?itok=rKJfXzmf 115 | :target: https://spatial.uchicago.edu 116 | :alt: CSDS is an initiative of the Division of Social Sciences and part of the UChicago's investment in computational social science. -------------------------------------------------------------------------------- /docsrc/source/install.rst: -------------------------------------------------------------------------------- 1 | .. _install_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 2 Installation 6 | ============== 7 | 8 | Like GeoDa desktop software, pygeoda are avaiable to 9 | different platforms including Mac, Linux, and Windows. 10 | You can install pygeoda using pip: 11 | :: 12 | 13 | pip install pygeoda 14 | 15 | 16 | To install pygeoda from source: 17 | 18 | 2.1 Windows 19 | ----------- 20 | 21 | For Windows users, Microsoft Visual C++ needs to be installed first. 22 | Please see https://wiki.python.org/moin/WindowsCompilers to find which Visual 23 | C++ compiler to use with a specific python version. 24 | 25 | Install pygeoda from source using pip: 26 | :: 27 | 28 | pip install git+https://github.com/GeoDaCenter/pygeoda 29 | 30 | 2.2 Linux 31 | --------- 32 | 33 | For Linux users, the “Build Essential Tools” needs to be installed first: 34 | :: 35 | 36 | sudo apt-get update 37 | sudo apt-get install build-essential 38 | 39 | Install pygeoda from source using pip: 40 | :: 41 | 42 | pip install git+https://github.com/GeoDaCenter/pygeoda 43 | 44 | 2.3 Mac 45 | ------- 46 | 47 | For Mac users, the “Xcode Command Line Tools” needs to be 48 | installed for installing pygeoda from source. 49 | It is a free software provided by Apple, which can be installed 50 | by using the following command in a terminal: 51 | :: 52 | 53 | xcode-select --install 54 | 55 | Install pygeoda from source using pip: 56 | :: 57 | 58 | pip install git+https://github.com/GeoDaCenter/pygeoda 59 | 60 | 2.4 Import pygeoda 61 | ------------------ 62 | 63 | If everything installed without error, you should be able to import pygeoda in Python: 64 | :: 65 | 66 | import pygeoda 67 | -------------------------------------------------------------------------------- /docsrc/source/intro.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 1. Introduction to pygeoda 6 | ========================== 7 | 8 | pygeoda is a python library for spatial data analysis based on libgeoda, 9 | which is a non-UI and API-based C++ library. It is designed for programmers to 10 | do spatial data analysis using their favorite programming languages 11 | (R, Python, Javascript, etc.). It also aims to be easily integrated with other 12 | libraries, software, or systems on different platforms. 13 | 14 | 15 | 1.1 Open Resources 16 | ------------------ 17 | 18 | * The pygeoda is open-sourced at: https://github.com/GeoDaCenter/pygeoda. 19 | 20 | If you prefer programming in R, you can try **rgeoda** for spatial data analysis: 21 | 22 | * The rgeoda is open-sourced at: https://github.com/GeoDaCenter/rgeoda. 23 | 24 | If you have any questions or issues, please open a ticket in one of the above repositories. 25 | 26 | .. note:: 27 | Since pygeoda is under active development, this document will be updated frequently. Please "watch" this github repository to get notifications. -------------------------------------------------------------------------------- /docsrc/source/load_data.rst: -------------------------------------------------------------------------------- 1 | .. _load_data_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 3 Load Spatial Data 6 | =================== 7 | 8 | pygeoda supports reading the ESRI ShapeFiles. For other data formats, 9 | please use `geopandas `_ to load the spatial data first, 10 | then pass the geopandas object to function `pygeoda.open()`. 11 | 12 | For example, to load the ESRI Shapefile **Guerry.shp** 13 | download from: https://geodacenter.github.io/data-and-lab/Guerry/. 14 | 15 | :: 16 | 17 | >>> import pygeoda 18 | >>> guerry = pygeoda.open("./data/Guerry.shp") 19 | >>> guerry 20 | geoda object: 21 | Number of observations: 85 22 | Number of fields: 27 23 | Geometry type(s): Polygon 24 | field name: field type (shapfile): 25 | CODE_DE string 26 | COUNT real 27 | AVE_ID_ real 28 | ... 29 | 30 | The geopandas can be used to load or manipulate spatial data first. 31 | Then, the geopandas object can be used to create a geoda object using 32 | the same function `pygeoda.open()`: 33 | 34 | :: 35 | 36 | >>> import geopandas 37 | >>> df = geopandas.read_file("./data/Guerry.shp") 38 | >>> 39 | >>> import pygeoda 40 | >>> guerry = pygeoda.open(df) 41 | >>> guerry 42 | geoda object: 43 | Number of observations: 85 44 | Number of fields: 27 45 | Geometry type(s): ('MultiPolygon', 'Polygon') 46 | field name: field type (numpy.dtype): 47 | CODE_DE object 48 | COUNT float64 49 | AVE_ID_ float64 50 | ... 51 | 52 | .. note:: 53 | The "Geometry type(s)" and "field type" are different from using 54 | pygeoda.open() function to open an ESRI shapefile and a geopandas object. 55 | When opening an ESRI shapefile, the "Geometry type" could be one of 56 | {'Polygon', 'Point', 'Line'} and the "field type" could be one of 57 | {'real', 'string', 'integer'}. When opening a geopandas object, the 58 | "Geometry type" is the defined by `GeoSeries `_ 59 | (e.g. MultiPolygon, Polygon, etc.) and the "field type" is defined by `numpy.dtype` 60 | (e.g. object, float64, int64, etc.) 61 | 62 | 63 | 3.1 Attributes of geoda object 64 | ------------------------------ 65 | 66 | * n_cols 67 | * n_obs 68 | * field_names 69 | * field_types 70 | 71 | To access the meta-data of the loaded Guerry dataset: 72 | :: 73 | 74 | >>> print("number of columns:", guerry.num_cols) 75 | number of columns: 26 76 | 77 | >>> print("number of observations:", guerry.num_obs) 78 | number of observations: 85 79 | 80 | >>> print("field names:", guerry.field_names) 81 | field names: ('CODE_DE', 'COUNT', 'AVE_ID_', 'dept', 'Region', 'Dprtmnt', 'Crm_prs', 'Crm_prp', 'Litercy', 'Donatns', 'Infants', 'Suicids', 'MainCty', 'Wealth', 'Commerc', 'Clergy', 'Crm_prn', 'Infntcd', 'Dntn_cl', 'Lottery', 'Desertn', 'Instrct', 'Prsttts', 'Distanc', 'Area', 'Pop1831') 82 | 83 | >>> print("field types:", guerry.field_types) 84 | field types: {'CODE_DE': 'string', 'COUNT':'real', 'AVE_ID_': 'real',...} 85 | 86 | .. note:: 87 | If using geopandas object in `pygeoda.open()`, there will be a geometry column "geometry" with data type "geometry". 88 | 89 | 3.2 Access Table Data 90 | --------------------- 91 | 92 | One can use the bracket `[ ]` operator to access the table data: 93 | 94 | >>> guerry = pygeoda.open('./data/Guerry.shp') 95 | >>> guerry['Crm_prs'] 96 | (28870.0, 26226.0, 26747.0, 12935.0,...) 97 | >>> guerry[['Crm_prs', 'Litercy']] 98 | [(28870.0, 26226.0, 26747.0, 12935.0,...), (37.0, 51.0, 13.0,...)] 99 | 100 | 101 | .. note:: 102 | If using geopandas object in `pygeoda.open()`, there output of `[[ ]]` operator is a dataframe object, which can be 103 | used as an input parameter in pygeoda functions like `skater()`, `neighbor_match_test()`, etc. 104 | 105 | :: 106 | 107 | >>> guerry = pygeoda.open(df) 108 | >>> guerry['Crm_prs'] 109 | [28870.0, 26226.0, 26747.0, 12935.0,...] 110 | >>> guerry[['Crm_prs', 'Litercy']] 111 | Crm_prs Litercy 112 | -------------------- 113 | 0 28880 37 114 | 1 26226 51 115 | 116 | 117 | .. note:: 118 | In pygeoda, to pass the values of a single variable to a pygeoda function, one can use either a tuple or list; 119 | to pass the values of multiple variables, one can use either a list of tuples/lists or a `dataframe `_. -------------------------------------------------------------------------------- /docsrc/source/map_classification.rst: -------------------------------------------------------------------------------- 1 | .. _map_classification_ref: 2 | 3 | .. currentmodule:: pygeoda 4 | 5 | 4 Map Classification 6 | ==================== 7 | 8 | pygeoda provids following methods for univariate map classification: 9 | 10 | * Hinge box breaks: hinge15_breaks() and hinge30_breaks() 11 | * Natural breaks: natural_breaks() 12 | * Quantile breaks: quantile_breaks() 13 | * Percentile breaks: percentile_breaks() 14 | * Standard deviation breaks: stddev_breaks() 15 | 16 | These methods of map classification calculate a corresponding breakpoint 17 | list for a selected variable. For more information about the map classification, please read Dr. Luc Anselin's lab note: 18 | http://geodacenter.github.io/workbook/6a_local_auto/lab6a.html. 19 | 20 | 21 | 4.1 Hinge Box Breaks 22 | -------------------- 23 | 24 | Hinge Box Breaks calculates a list of breakpoints, including the top, bottom, median, 25 | and two quartiles of the data. Here the hinge can be 1.5 or 3.0. For example, we can 26 | call function `hinge15_breaks()` or `hinge30_breaks` with the data "Crm_prp" as input 27 | parameter: 28 | :: 29 | 30 | >>> breaks15 = pygeoda.hinge15_breaks(guerry['Crm_prp']) 31 | >>> print(breaks15) 32 | (1190.0, 5990.0, 7624.0, 9190.0, 13990.0) 33 | 34 | >>> breaks30 = pygeoda.hinge30_breaks(guerry['Crm_prp']) 35 | >>> print(breaks30) 36 | (-3610.0, 5990.0, 7624.0, 9190.0, 18790.0) 37 | 38 | 39 | 4.2 Natural Breaks 40 | ------------------ 41 | 42 | Natural Breaks calculates a list of breakpoints based on the fracture principle of 43 | maximum similarity within a group. For example, we can call function `natural_breaks()` 44 | with the data "Crm_prp" and the number of classification “k” as input parameters: 45 | :: 46 | 47 | >>> breaks = pygeoda.natural_breaks(5, guerry['Crm_prp']) 48 | >>> print(breaks) 49 | (5521.0, 7204.0, 10237.0, 15890.0) 50 | 51 | 52 | 4.3 Quantile Breaks 53 | ------------------- 54 | 55 | Quantile Breaks is based on sorted values for a variable that are then grouped 56 | into bins that each have the same number of observations, the so-called quantiles. 57 | For example, we can call function `quantile_breaks()` with the data "Crm_prp", 58 | and the number of classification “k” as input parameters: 59 | :: 60 | 61 | >>> breaks = pygeoda.quantile_breaks(5, guerry['Crm_prp']) 62 | >>> print(breaks) 63 | (5439.0, 6886.0, 8205.0, 9584.5) 64 | 65 | 66 | 4.4 Percentile Breaks 67 | --------------------- 68 | 69 | Percentile Breaks divides the data into six ranges: the lowest 1%, 1-10%, 10-50%, 70 | 50-90%, 90-99% and the top 1%. It returns the range boundaries as a breakpoint list. 71 | For example, we can call function `natural_breaks()` with the data "Crm_prp" as 72 | input parameter: 73 | :: 74 | 75 | >>> breaks = pygeoda.percentile_breaks(guerry['Crm_prp']) 76 | >>> print(breaks) 77 | (1906.3, 4529.0, 7624.0, 10954.0, 19467.8) 78 | 79 | 80 | 4.5 Standard Deviation Breaks 81 | ----------------------------- 82 | 83 | Standard Deviation Breaks calculates the number of standard deviational units of the 84 | range from lowest to highest, returning a breakpoint list. For example, we can 85 | call function `stddev_breaks()` with the data "Crm_prp" as input parameter: 86 | :: 87 | 88 | >>> breaks = pygeoda.stddev_breaks(guerry['Crm_prp']) 89 | >>> print(breaks) 90 | (1784.1106064421238, 4832.725891456355, 7881.341176470588, 10929.95646148482, 13978.571746499052) 91 | 92 | -------------------------------------------------------------------------------- /libgeoda.i: -------------------------------------------------------------------------------- 1 | %module libgeoda 2 | %begin %{ 3 | #define SWIG_PYTHON_2_UNICODE 4 | %} 5 | %include "stl.i" 6 | %include "std_string.i" 7 | %include "std_vector.i" 8 | %include "std_pair.i" 9 | 10 | 11 | %template(VecVoid) std::vector; 12 | %template(VecFloat) std::vector; 13 | %template(VecString) std::vector; 14 | %template(VecDouble) std::vector; 15 | %template(VecChar) std::vector; 16 | %template(VecCharPointer) std::vector; 17 | %template(VecVecDouble) std::vector >; 18 | %template(VecInt) std::vector; 19 | %template(VecBool) std::vector; 20 | %template(VecVecBool) std::vector >; 21 | %template(VecLong) std::vector; 22 | %template(VecInt64) std::vector; 23 | %template(VecVecInt) std::vector >; 24 | %template(VecUINT8) std::vector; 25 | %template(VecVecUINT8) std::vector >; 26 | %template(VecVecChar) std::vector >; 27 | %template(Pair) std::pair >; 28 | %template(VecPair) std::vector > >; 29 | 30 | 31 | #if defined(SWIGPYTHON) 32 | 33 | %typemap(ignore) TYPEMAP(unsigned char* temp) { 34 | $1 = ($1_ltype) temp; 35 | } 36 | 37 | %typemap(in) (unsigned char*) { 38 | // used by GeoDa() constructor for pygeoda 39 | if (!PyByteArray_Check($input)) { 40 | SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" "', argument " 41 | "$argnum"" of type '" "$type""'"); 42 | } 43 | $1 = (unsigned char*) PyByteArray_AsString($input); 44 | } 45 | 46 | %typemap(in) (std::vector) { 47 | // vector of bytes for geopands_to_geoda() 48 | int iLen = PySequence_Length($input); 49 | for(unsigned int i = 0; i < iLen; i++) { 50 | PyObject *o = PySequence_GetItem($input, i); 51 | $1.push_back((char*)(PyBytes_AsString(o))); 52 | } 53 | } 54 | #endif 55 | 56 | %{ 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | %} 71 | 72 | // release memory for some function to prevent memory leaking 73 | // the SWIG generated wrappers will have a memory leak--the returned 74 | // data will be copied into a string object and the old contents ignored. 75 | %newobject gda_queen_weights; 76 | %newobject gda_rook_weights; 77 | %newobject gda_knn_weights; 78 | %newobject gda_distance_weights; 79 | %newobject gda_localmoran; 80 | %newobject gda_batchlocalmoran; 81 | %newobject gda_localgeary; 82 | %newobject gda_localmultigeary; 83 | %newobject gda_localjoincount; 84 | %newobject gda_localmultijoincount; 85 | %newobject gda_localg; 86 | %newobject gda_localgstar; 87 | %newobject gda_quantilelisa; 88 | %newobject gda_multiquantilelisa; 89 | %newobject gda_fdr; 90 | %newobject gda_bo; 91 | %newobject CreateGeoDaFromGPD; 92 | %newobject CreateGeoDaFromSHP; 93 | 94 | %include 95 | %include 96 | %include 97 | %include 98 | %include 99 | %include 100 | %include 101 | %include 102 | %include 103 | %include 104 | %include 105 | 106 | %template(VecGeoDaColumn) std::vector; 107 | %template(VecJoinCountRatio) std::vector; 108 | %template(VecCompactness) std::vector; 109 | %template(VecDiameter) std::vector; 110 | %template(VecFragmentation) std::vector; 111 | 112 | 113 | -------------------------------------------------------------------------------- /pygeoda/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.0.8-1" 2 | # __version__ has to be define in the first line 3 | 4 | __author__ = "Xun Li , " 5 | 6 | # exposed under pygeoda.xxx 7 | from .weights import * 8 | from .clustering import * 9 | from .sa import * 10 | from .gda import * 11 | from .classify import * 12 | from .data import * 13 | -------------------------------------------------------------------------------- /pygeoda/classify/__init__.py: -------------------------------------------------------------------------------- 1 | from .breaks import hinge15_breaks 2 | from .breaks import hinge30_breaks 3 | from .breaks import natural_breaks 4 | from .breaks import quantile_breaks 5 | from .breaks import percentile_breaks 6 | from .breaks import stddev_breaks 7 | 8 | 9 | -------------------------------------------------------------------------------- /pygeoda/classify/breaks.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_hinge15breaks 2 | from ..libgeoda import gda_hinge30breaks 3 | from ..libgeoda import gda_naturalbreaks 4 | from ..libgeoda import gda_quantilebreaks 5 | from ..libgeoda import gda_percentilebreaks 6 | from ..libgeoda import gda_stddevbreaks 7 | from ..libgeoda import VecBool 8 | 9 | __author__ = "Xun Li , Hang Zhang , " 10 | 11 | def hinge15_breaks(data,**kwargs): 12 | """(Box) Hinge15 Breaks 13 | 14 | Hinge15 breaks data into 6 groups like box plot groups (Lower outlier, < 25%, 25-50%, 50-75%, >75%, Upper outlier) with hinge=1.5 15 | 16 | Args: 17 | data (tuple): A tuple with values of a selected variable 18 | 19 | Returns: 20 | list: A numeric list of break values 21 | """ 22 | if data is None: 23 | raise("The data from selected variable is empty.") 24 | 25 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 26 | 27 | return gda_hinge15breaks(data, undefs) 28 | 29 | def hinge30_breaks(data,**kwargs): 30 | """(Box) Hinge30 Breaks 31 | 32 | Hinge30 breaks data into 6 groups like box plot groups (Lower outlier, < 25%, 25-50%, 50-75%, >75%, Upper outlier) with hinge=3.0 33 | 34 | Args: 35 | data (tuple): A tuple with values of a selected variable 36 | 37 | Returns: 38 | list: A numeric list of break values 39 | """ 40 | if data is None: 41 | raise("The data from selected variable is empty.") 42 | 43 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 44 | 45 | return gda_hinge30breaks(data, undefs) 46 | 47 | def natural_breaks(k,data,**kwargs): 48 | """Natural Breaks (Jenks) 49 | 50 | Natural Breaks group data whose boundaries are set where there are relatively big differences. 51 | 52 | Args: 53 | k (int): Number of breaks 54 | data (tuple): A tuple with values of a selected variable 55 | 56 | Returns: 57 | list: A numeric list of break values 58 | """ 59 | if k is None or k < 2: 60 | raise("The value of K needs to be greater than or equal to 2 ") 61 | 62 | if data is None: 63 | raise("The data from selected variable is empty.") 64 | 65 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 66 | return gda_naturalbreaks(k, data, undefs) 67 | 68 | def quantile_breaks(k,data,**kwargs): 69 | """Quantile breaks 70 | 71 | Quantile breaks data into groups that each have the same number of observations 72 | 73 | Args: 74 | k (int): Number of breaks 75 | data (tuple): A tuple with values of a selected variable 76 | 77 | Returns: 78 | list: A numeric list of break values 79 | """ 80 | if k is None or k < 2: 81 | raise("The value of K needs to be greater than or equal to 2 ") 82 | 83 | if data is None: 84 | raise("The data from selected variable is empty.") 85 | 86 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 87 | return gda_quantilebreaks(k, data, undefs) 88 | 89 | def percentile_breaks(data,**kwargs): 90 | """Percentile breaks 91 | 92 | Note: 93 | The percentile breaks divides the data to six ranges, the lowest 1%, 1-10%, 10-50%, 50-90%, 90-99% and the top 1%, returning the range boundaries as a breakpoint list. 94 | 95 | Args: 96 | data (tuple): A tuple with values of a selected variable 97 | 98 | Returns: 99 | list: A numeric list of break values 100 | """ 101 | if data is None: 102 | raise("The data from selected variable is empty.") 103 | 104 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 105 | return gda_percentilebreaks(data, undefs) 106 | 107 | def stddev_breaks(data,**kwargs): 108 | """Standard deviation breaks 109 | 110 | Note: 111 | Standard deviation breaks calculate the number of standard deviational units of the range from lowest to highest, returning a breakpoint list. 112 | Args: 113 | data (tuple): A tuple with values of a selected variable 114 | 115 | Returns: 116 | list: A numeric list of break values 117 | """ 118 | if data is None: 119 | raise("The data from selected variable is empty.") 120 | 121 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 122 | 123 | return gda_stddevbreaks(data, undefs) 124 | 125 | -------------------------------------------------------------------------------- /pygeoda/clustering/__init__.py: -------------------------------------------------------------------------------- 1 | from .redcap import redcap 2 | from .skater import skater 3 | from .maxp import maxp_greedy, maxp_sa, maxp_tabu 4 | from .azp import azp_greedy, azp_sa, azp_tabu 5 | from .schc import schc 6 | from .validation import spatial_validation, make_spatial, ValidationResult, Diameter, Compactness, JoinCountRatio, Fragmentation -------------------------------------------------------------------------------- /pygeoda/clustering/redcap.py: -------------------------------------------------------------------------------- 1 | from pygeoda.clustering.utils import calculate_clustering_statistics 2 | from ..libgeoda import VecVecDouble 3 | from ..libgeoda import gda_redcap 4 | 5 | __author__ = "Xun Li , " 6 | 7 | def redcap(k, w, data, method, **kwargs): 8 | ''' Regionalization with dynamically constrained agglomerative clustering and partitioning (REDCAP) 9 | 10 | REDCAP starts from building a spanning tree with 4 different ways (single-linkage, average-linkage, complete-linkage and Ward-linkage). 11 | Then, REDCAP provides 2 different ways to prune the tree (First-order and Full-order) to build clusters. 12 | In pygeoda, the following methods are provided: 13 | 14 | * First-order and Single-linkage 15 | * Full-order and Single-linkage 16 | * Full-order and Complete-linkage 17 | * Full-order and Average-linkage 18 | * Full-order and Ward-linkage 19 | 20 | Arguments: 21 | k (int): number of clusters 22 | w (Weight): An instance of Weight class 23 | data (list or dataframe): A list of numeric vectors of selected variable or a data frame of selected variables e.g. guerry[['Crm_prs', 'Literacy']] 24 | bound_variable (tuple or pandas.core.series.Series, optional): A numeric vector of selected bounding variable 25 | min_bound (float, optional): a minimum value that the sum value of bounding variable int each cluster should be greater than 26 | scale_method (str, optional): One of the scaling methods {'raw', 'standardize', 'demean', 'mad', 'range_standardize', 'range_adjust'} to apply on input data. Default is 'standardize' (Z-score normalization). 27 | distance_method (str, optional): {"euclidean", "manhattan"} the distance method used to compute the distance betwen observation i and j. Defaults to "euclidean". Options are "euclidean" and "manhattan" 28 | random_seed (int,optional): the seed for random number generator. Defaults to 123456789. 29 | cpu_threads (int, optional): The number of cpu threads used for parallel computation 30 | 31 | Returns: 32 | dict: A dict with keys {"Clusters", "TotalSS", "Within-clusterSS", "TotalWithin-clusterSS", "Ratio"} 33 | ''' 34 | 35 | min_bound = 0 if 'min_bound' not in kwargs else kwargs['min_bound'] 36 | bound_variable = [] if 'bound_variable' not in kwargs else kwargs['bound_variable'] 37 | scale_method = "standardize" if "scale_method" not in kwargs else kwargs['scale_method'] 38 | distance_method = 'euclidean' if 'distance_method' not in kwargs else kwargs['distance_method'] 39 | random_seed = 123456789 if 'random_seed' not in kwargs else kwargs['random_seed'] 40 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 41 | 42 | if method not in ['firstorder-singlelinkage', 'fullorder-singlelinkage', 'fullorder-averagelinkage', 'fullorder-completelinkage', 'fullorder-wardlinkage']: 43 | raise ValueError('The method has to be one of {"firstorder-singlelinkage", "fullorder-completelinkage", "fullorder-averagelinkage","fullorder-singlelinkage", "fullorder-wardlinkage"}') 44 | 45 | # check if bound_variable is pandas.core.series.Series, if so, convert to list 46 | if type(bound_variable).__name__ == "Series": 47 | bound_variable = bound_variable.values.tolist() 48 | 49 | # if bound_variable is not empty, check if it has the same length as the number of observations 50 | if len(bound_variable) > 0 and len(bound_variable) != w.num_obs: 51 | raise ValueError("The bound_variable has to be a list of numeric values, e.g. a column of input table.") 52 | 53 | # check if min_bound is available when bound_variable is not empty 54 | if len(bound_variable) > 0 and min_bound == 0: 55 | raise ValueError("min_bound is required and greater than 0 when bound_variable is not empty.") 56 | 57 | if type(data).__name__ == "DataFrame": 58 | data = data.values.transpose().tolist() 59 | 60 | in_data = VecVecDouble() 61 | for d in data: 62 | in_data.push_back(d) 63 | 64 | #in_bound_variable = VecDouble(bound_variable) 65 | 66 | cluster_ids = gda_redcap(k, w.gda_w, in_data, scale_method, method, distance_method, bound_variable, min_bound, random_seed, cpu_threads) 67 | 68 | return calculate_clustering_statistics(cluster_ids, in_data, w.num_obs) 69 | -------------------------------------------------------------------------------- /pygeoda/clustering/schc.py: -------------------------------------------------------------------------------- 1 | from pygeoda.clustering.utils import calculate_clustering_statistics 2 | from ..libgeoda import VecVecDouble 3 | from ..libgeoda import gda_schc 4 | 5 | __author__ = "Xun Li , " 6 | 7 | def schc(k, w, data, linkage_method, **kwargs): 8 | ''' Spatially Constrained Hierarchical Clucstering (SCHC) 9 | 10 | Spatially constrained hierarchical clustering is a special form of constrained 11 | clustering, where the constraint is based on contiguity (common borders). 12 | The method builds up the clusters using agglomerative hierarchical clustering 13 | methods: single linkage, complete linkage, average linkage and Ward's method 14 | (a special form of centroid linkage). Meanwhile, it also maintains the spatial 15 | contiguity when merging two clusters. 16 | 17 | Arguments: 18 | k (int): number of clusters 19 | w (Weight): An instance of Weight class 20 | data (tuple): A list of numeric vectors of selected variable 21 | linkage_method (str): The method of agglomerative hierarchical clustering: {"single", "complete", "average","ward"}. Defaults to "ward". 22 | bound_variable (tuple or pandas.core.series.Series, optional): A numeric vector of selected bounding variable 23 | min_bound (float, optional): a minimum value that the sum value of bounding variable int each cluster should be greater than 24 | scale_method (str, optional): One of the scaling methods {'raw', 'standardize', 'demean', 'mad', 'range_standardize', 'range_adjust'} to apply on input data. Default is 'standardize' (Z-score normalization). 25 | distance_method (str, optional): {"euclidean", "manhattan"} the distance method used to compute the distance betwen observation i and j. Defaults to "euclidean". Options are "euclidean" and "manhattan" 26 | 27 | Returns: 28 | dict: A dict with keys {"Clusters", "TotalSS", "Within-clusterSS", "TotalWithin-clusterSS", "Ratio"} 29 | ''' 30 | 31 | min_bound = 0 if 'min_bound' not in kwargs else kwargs['min_bound'] 32 | bound_variable = [] if 'bound_variable' not in kwargs else kwargs['bound_variable'] 33 | scale_method = "standardize" if "scale_method" not in kwargs else kwargs['scale_method'] 34 | distance_method = 'euclidean' if 'distance_method' not in kwargs else kwargs['distance_method'] 35 | 36 | if linkage_method not in ["single", "complete", "average", "ward"]: 37 | raise ValueError('The method has to be one of {"single", "complete", "average", "ward"}') 38 | 39 | # check if bound_variable is pandas.core.series.Series, if so, convert to list 40 | if type(bound_variable).__name__ == "Series": 41 | bound_variable = bound_variable.values.tolist() 42 | 43 | # if bound_variable is not empty, check if it has the same length as the number of observations 44 | if len(bound_variable) > 0 and len(bound_variable) != w.num_obs: 45 | raise ValueError("The bound_variable has to be a list of numeric values, e.g. a column of input table.") 46 | 47 | # check if min_bound is available when bound_variable is not empty 48 | if len(bound_variable) > 0 and min_bound == 0: 49 | raise ValueError("min_bound is required and greater than 0 when bound_variable is not empty.") 50 | 51 | if type(data).__name__ == "DataFrame": 52 | data = data.values.transpose().tolist() 53 | 54 | in_data = VecVecDouble() 55 | for d in data: 56 | in_data.push_back(d) 57 | 58 | cluster_ids = gda_schc(k, w.gda_w, in_data, scale_method, linkage_method, distance_method, bound_variable, min_bound) 59 | 60 | return calculate_clustering_statistics(cluster_ids, in_data, w.num_obs) -------------------------------------------------------------------------------- /pygeoda/clustering/skater.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from pygeoda.clustering.utils import calculate_clustering_statistics 4 | from ..libgeoda import VecVecDouble 5 | from ..libgeoda import gda_skater 6 | 7 | def skater(k, w, data, **kwargs): 8 | ''' Spatial C(K)luster Analysis by Tree Edge Removal 9 | 10 | SKATER forms clusters by spatially partitioning data that has similar values for features of interest. 11 | 12 | Arguments: 13 | k (int): number of clusters 14 | w (Weight): An instance of Weight class 15 | data (list or dataframe): A list of numeric vectors of selected variable or a data frame of selected variables e.g. guerry[['Crm_prs', 'Literacy']] 16 | bound_variable (tuple or pandas.core.series.Series, optional): A numeric vector of selected bounding variable 17 | min_bound (float, optional): a minimum value that the sum value of bounding variable int each cluster should be greater than 18 | scale_method (str, optional): One of the scaling methods {'raw', 'standardize', 'demean', 'mad', 'range_standardize', 'range_adjust'} to apply on input data. Default is 'standardize' (Z-score normalization). 19 | distance_method (str, optional): {"euclidean", "manhattan"} the distance method used to compute the distance betwen observation i and j. Defaults to "euclidean". Options are "euclidean" and "manhattan" 20 | random_seed (int,optional): the seed for random number generator. Defaults to 123456789. 21 | cpu_threads (int, optional): The number of cpu threads used for parallel computation 22 | 23 | Return: 24 | dict: A dict with keys {"Clusters", "TotalSS", "Within-clusterSS", "TotalWithin-clusterSS", "Ratio"} 25 | 26 | ''' 27 | min_bound = 0 if 'min_bound' not in kwargs else kwargs['min_bound'] 28 | bound_variable = [] if 'bound_variable' not in kwargs else kwargs['bound_variable'] 29 | scale_method = "standardize" if "scale_method" not in kwargs else kwargs['scale_method'] 30 | distance_method = 'euclidean' if 'distance_method' not in kwargs else kwargs[ 31 | 'distance_method'] 32 | random_seed = 123456789 if 'random_seed' not in kwargs else kwargs['random_seed'] 33 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 34 | 35 | # check if bound_variable is pandas.core.series.Series, if so, convert to list 36 | if type(bound_variable).__name__ == "Series": 37 | bound_variable = bound_variable.values.tolist() 38 | 39 | # if bound_variable is not empty, check if it has the same length as the number of observations 40 | if len(bound_variable) > 0 and len(bound_variable) != w.num_obs: 41 | raise ValueError( 42 | "The bound_variable has to be a list of numeric values, e.g. a column of input table.") 43 | 44 | # check if min_bound is available when bound_variable is not empty 45 | if len(bound_variable) > 0 and min_bound == 0: 46 | raise ValueError( 47 | "min_bound is required and greater than 0 when bound_variable is not empty.") 48 | 49 | if type(data).__name__ == "DataFrame": 50 | data = data.values.transpose().tolist() 51 | 52 | in_data = VecVecDouble() 53 | for d in data: 54 | in_data.push_back(d) 55 | 56 | cluster_ids = gda_skater(k, w.gda_w, in_data, scale_method, distance_method, 57 | bound_variable, min_bound, random_seed, cpu_threads) 58 | 59 | return calculate_clustering_statistics(cluster_ids, in_data, w.num_obs) 60 | -------------------------------------------------------------------------------- /pygeoda/clustering/utils.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_betweensumofsquare, gda_totalsumofsquare, gda_withinsumofsquare, flat_2dclusters 2 | 3 | def calculate_clustering_statistics(cluster_ids, in_data, num_obs): 4 | """Calculate clustering statistics including sum of squares measures. 5 | 6 | Args: 7 | cluster_ids: Cluster assignments for each observation 8 | in_data: Input data in VecVecDouble format 9 | num_obs: Number of observations 10 | 11 | Returns: 12 | dict: Dictionary containing clustering statistics: 13 | - Total sum of squares 14 | - Within-cluster sum of squares 15 | - Between-cluster sum of squares (Total within-cluster sum of squares) 16 | - Ratio of between to total sum of squares 17 | - Clusters (flattened cluster assignments) 18 | """ 19 | between_ss = gda_betweensumofsquare(cluster_ids, in_data) 20 | total_ss = gda_totalsumofsquare(in_data) 21 | ratio = between_ss / total_ss 22 | within_ss = gda_withinsumofsquare(cluster_ids, in_data) 23 | # for the case that constraint is used, the length of within_ss is not the same as cluster_ids 24 | # check if the length of within_ss is the same as cluster_ids 25 | # if not, add 0 to the within_ss to make it the same length as cluster_ids 26 | if len(within_ss) != len(cluster_ids): 27 | within_ss = [0]*(len(cluster_ids) - len(within_ss)) + list(within_ss) 28 | 29 | return { 30 | "Total sum of squares": total_ss, 31 | "Within-cluster sum of squares": within_ss, 32 | "Total within-cluster sum of squares": sum(within_ss), 33 | "Total between-cluster sum of squares": between_ss, 34 | "The ratio of between to total sum of squares": ratio, 35 | "Clusters": flat_2dclusters(num_obs, cluster_ids), 36 | } 37 | -------------------------------------------------------------------------------- /pygeoda/data/__init__.py: -------------------------------------------------------------------------------- 1 | from .transform import demean, standardize, mad -------------------------------------------------------------------------------- /pygeoda/data/transform.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_demean, gda_standardize, gda_standardize_mad 2 | 3 | ''' 4 | 1/19/2021: add demean, standardize, standardize_mad 5 | ''' 6 | __author__ = "Xun Li , " 7 | 8 | def demean(data): 9 | """Demean Standardization 10 | 11 | Note: 12 | The mean for each variable is subtracting from each observation resulting in mean zero. 13 | 14 | Args: 15 | data (list): An input data of multiple variables for median absolute deviation 16 | 17 | Returns: 18 | list: A data array 19 | """ 20 | if data is None: 21 | raise ValueError("The data from selected variable is empty.") 22 | 23 | return gda_demean(data) 24 | 25 | 26 | def standardize(data): 27 | """Standardization (Z) 28 | 29 | Note: 30 | Standarize data by transforming data to have zero mean and unit variance. 31 | 32 | Args: 33 | data (list): An input data of multiple variables for standardization 34 | 35 | Returns: 36 | list: A data array 37 | """ 38 | if data is None: 39 | raise ValueError("The data from selected variable is empty.") 40 | 41 | return gda_standardize(data) 42 | 43 | def mad(data): 44 | """Median Absolute Deviation 45 | 46 | Note: 47 | Compute the median absolute deviation, i.e., the (lo-/hi-) median of the absolute deviations from the median, and (by default) adjust by a factor for asymptotically normal consistency. 48 | 49 | Args: 50 | data (list): An input data of multiple variables for standardization 51 | 52 | Returns: 53 | list: A data array 54 | """ 55 | if data is None: 56 | raise ValueError("The data from selected variable is empty.") 57 | 58 | return gda_standardize_mad(data) -------------------------------------------------------------------------------- /pygeoda/sa/__init__.py: -------------------------------------------------------------------------------- 1 | from .moran import local_moran, batch_local_moran, local_bimoran 2 | from .geary import local_geary, local_multigeary 3 | from .joincount import local_joincount, local_multijoincount, local_bijoincount 4 | from .getisord import local_g, local_gstar 5 | from .lisa import lisa, batchlisa 6 | from .quantile_lisa import local_quantilelisa, local_multiquantilelisa 7 | from .neighbor_match_test import neighbor_match_test -------------------------------------------------------------------------------- /pygeoda/sa/geary.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from ..libgeoda import VecBool, VecVecBool 4 | from ..libgeoda import gda_localgeary, gda_localmultigeary 5 | from .lisa import lisa 6 | 7 | ''' 8 | Changes: 9 | 1/21/2021 Update local_multigeary, local_geary for 0.0.6 10 | ''' 11 | 12 | def local_multigeary(w, data, **kwargs): 13 | '''Local Multivariate Geary Statistics 14 | 15 | The function to apply local Multivariate Geary statistics 16 | 17 | Args: 18 | w (Weight): An instance of Weight class 19 | data (list/pandas.dataframe): A list of numeric tuples with values of selected variables 20 | undefs (list, optional): A list of boolean values to indicate which value is undefined or null 21 | permutations (int, optional): The number of permutations for the LISA computation 22 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 23 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 24 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 25 | seed (int, optional): The seed for random number generator 26 | 27 | Returns: 28 | lisa: An instance of lisa class 29 | ''' 30 | if w == None: 31 | raise ValueError("Weights is None.") 32 | 33 | undefs = VecVecBool() if 'undefs' not in kwargs else kwargs['undefs'] 34 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 35 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 36 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 37 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 38 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 39 | 40 | if type(data).__name__ == "DataFrame": 41 | data = data.values.transpose().tolist() 42 | 43 | lisa_obj = gda_localmultigeary(w.gda_w, data, undefs, significance_cutoff, cpu_threads, permutations, permutation_method, seed) 44 | return lisa(lisa_obj) 45 | 46 | def local_geary(w, data, **kwargs): 47 | '''Local Geary Statistics 48 | 49 | The function to apply local Geary statistics 50 | 51 | Args: 52 | w (Weight): An instance of Weight class. 53 | data (tuple/list/pandas.Series): A list of numeric values of selected variable 54 | undefs (list, optional): A list of boolean values to indicate which value is undefined or null 55 | permutations (int, optional): The number of permutations for the LISA computation 56 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 57 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 58 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 59 | seed (int, optional): The seed for random number generator 60 | 61 | Returns: 62 | lisa: An instance of lisa class 63 | ''' 64 | if w == None: 65 | raise ValueError("Weights is None.") 66 | 67 | if w.num_obs != len(data): 68 | raise ValueError("The size of data doesnt not match the number of observations.") 69 | 70 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 71 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 72 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 73 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 74 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 75 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 76 | 77 | lisa_obj = gda_localgeary(w.gda_w, list(data), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 78 | return lisa(lisa_obj) -------------------------------------------------------------------------------- /pygeoda/sa/getisord.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from ..libgeoda import gda_localg, gda_localgstar, VecBool 4 | from .lisa import lisa 5 | import multiprocessing 6 | 7 | def local_g(w, data, **kwargs): 8 | """Local Getis-Ord's G Statistics 9 | 10 | The function to apply Getis-Ord's local G statistics 11 | 12 | Args: 13 | w (Weight): An instance of Weight class. 14 | data (tuple/list/pandas.Series): A list of numeric values of selected variable 15 | undefs (list, optional): A list of boolean values to indicate which value is undefined or null 16 | permutations (int, optional): The number of permutations for the LISA computation 17 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 18 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 19 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 20 | seed (int, optional): The seed for random number generator 21 | 22 | Returns: 23 | lisa: An instance of lisa class 24 | """ 25 | if w == None: 26 | raise ValueError("Weights is None.") 27 | 28 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 29 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 30 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 31 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 32 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 33 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 34 | 35 | lisa_obj = gda_localg(w.gda_w, list(data), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 36 | return lisa(lisa_obj) 37 | 38 | def local_gstar(w, data, **kwargs): 39 | """Local Getis-Ord's G* Statistics 40 | The function to apply Getis-Ord's local G* statistics 41 | 42 | Args: 43 | w (Weight): An instance of Weight class. 44 | data (tuple/list/pandas.Series): A list of numeric values of selected variable 45 | undefs (list, optional): A list of boolean values to indicate which value is undefined or null 46 | permutations (int, optional): The number of permutations for the LISA computation 47 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 48 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 49 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 50 | seed (int, optional): The seed for random number generator 51 | 52 | Returns: 53 | lisa: An instance of lisa class 54 | """ 55 | if w == None: 56 | raise ValueError("Weights is None.") 57 | 58 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 59 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 60 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 61 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 62 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 63 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 64 | 65 | lisa_obj = gda_localgstar(w.gda_w, list(data), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 66 | return lisa(lisa_obj) -------------------------------------------------------------------------------- /pygeoda/sa/moran.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_localmoran, gda_bi_localmoran, VecBool, gda_batchlocalmoran, VecVecBool, gda_localmoran_eb 2 | from .lisa import lisa, batchlisa 3 | 4 | __author__ = "Xun Li " 5 | 6 | def local_moran(w, data, **kwargs): 7 | """Local Moran statistics. 8 | 9 | Args: 10 | w (Weight): An instance of Weight class. 11 | data (tuple/list/pandas.Series): A tuple of numeric values of selected variable 12 | undefs (tuple/list, optional): A tuple of boolean values to indicate which value is undefined or null 13 | permutations (int, optional): The number of permutations for the LISA computation 14 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 15 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 16 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 17 | seed (int, optional): The seed for random number generator 18 | 19 | Returns: 20 | lisa: An instance of lisa class represents the results of lisa computation 21 | """ 22 | if w == None: 23 | raise ValueError("Weights is None.") 24 | 25 | if w.num_obs != len(data): 26 | raise ValueError("The size of data doesnt not match the number of observations.") 27 | 28 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 29 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 30 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 31 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 32 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 33 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 34 | 35 | lisa_obj = gda_localmoran(w.gda_w, list(data), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 36 | return lisa(lisa_obj) 37 | 38 | def local_bimoran(w, data1, data2, **kwargs): 39 | """Bivariate local Moran statistics. 40 | The bivariate Local Moran’s I captures the relationship between the value for one variable at location i, and the average of the neighboring values for another variable. 41 | 42 | Args: 43 | w (Weight): An instance of Weight class. 44 | data1 (tuple/list/pandas.Series): A tuple of numeric values of first variable 45 | data1 (tuple/list/pandas.Series): A tuple of numeric values of second variable 46 | undefs (tuple/list, optional): A tuple of boolean values to indicate which value is undefined or null 47 | permutations (int, optional): The number of permutations for the LISA computation 48 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 49 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 50 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 51 | seed (int, optional): The seed for random number generator 52 | 53 | Returns: 54 | lisa: An instance of lisa class represents the results of lisa computation 55 | """ 56 | if w == None: 57 | raise ValueError("Weights is None.") 58 | 59 | if w.num_obs != len(data1) or len(data1) != len(data2): 60 | raise ValueError("The size of data doesnt not match the number of observations.") 61 | 62 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 63 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 64 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 65 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 66 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 67 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 68 | 69 | lisa_obj = gda_bi_localmoran(w.gda_w, list(data1), list(data2), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 70 | return lisa(lisa_obj) 71 | 72 | def local_moran_eb(w, event_data, base_data, **kwargs): 73 | """The function to apply local Moran with EB Rate statistics. 74 | The EB rate is first computed from "event" and "base" variables, and then used in local moran statistics. 75 | 76 | Args: 77 | w (Weight): An instance of Weight class 78 | event_data (tuple/list/pandas.Series): A numeric tuple of selected "event" variable 79 | base_data (tuple/list/pandas.Series): A numeric tuple of selected "base" variable 80 | permutations (int, optional): The number of permutations for the LISA computation 81 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 82 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 83 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 84 | seed (int, optional): The seed for random number generator 85 | 86 | Returns: 87 | lisa: An instance of lisa class represents the results of lisa computation 88 | """ 89 | if w == None: 90 | raise ValueError("Weights is None.") 91 | 92 | if w.num_obs != len(event_data) or w.num_obs != len(base_data): 93 | raise ValueError("The size of data doesnt not match the number of observations.") 94 | 95 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 96 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 97 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 98 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 99 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 100 | 101 | lisa_obj = gda_localmoran_eb(w.gda_w, list(event_data), list(base_data), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 102 | return lisa(lisa_obj) 103 | 104 | def batch_local_moran(w, data, **kwargs): 105 | """Apply local moran statistics on a set of variables 106 | 107 | Args: 108 | w (Weight): An instance of Weight class. 109 | data (list/pandas.dataframe): A list of numeric array of selected variables 110 | permutations (int, optional): The number of permutations for the LISA computation 111 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 112 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 113 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 114 | seed (int, optional): The seed for random number generator 115 | 116 | Returns: 117 | lisa: An instance of BatchLisa class represents the results of lisa computations 118 | """ 119 | if w == None: 120 | raise ValueError("Weights is None.") 121 | 122 | if (not isinstance(data, list)) or (len(data) < 1): 123 | raise ValueError("The data has to be a list of numeric array of selected variables.") 124 | 125 | if w.num_obs != len(data[0]): 126 | raise ValueError("The size of data doesnt not match the number of observations.") 127 | 128 | if type(data).__name__ == "DataFrame": 129 | data = data.values.transpose().tolist() 130 | 131 | undefs = VecVecBool() if 'undefs' not in kwargs else kwargs['undefs'] 132 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 133 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 134 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 135 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 136 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 137 | 138 | lisa_obj = gda_batchlocalmoran(w.gda_w, data, undefs, significance_cutoff, cpu_threads, permutations, permutation_method, seed) 139 | return batchlisa(lisa_obj) -------------------------------------------------------------------------------- /pygeoda/sa/neighbor_match_test.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from ..libgeoda import VecBool, VecVecBool 4 | from ..libgeoda import gda_neighbor_match_test, VecVecDouble 5 | from .lisa import lisa 6 | import math 7 | 8 | ''' 9 | Changes: 10 | 1/21/2021 Update local_multigeary, local_geary for 0.0.6 11 | ''' 12 | 13 | def neighbor_match_test(geoda_obj, data, k, **kwargs): 14 | '''Local Neighbor Match Test 15 | The local neighbor match test is to assess the extent of overlap between k-nearest neighbors in geographical space and k-nearest neighbors in multi-attribute space. 16 | 17 | Args: 18 | geoda_obj (geoda): An instance of geoda class. 19 | data (list or dataframe): A list of numeric vectors of selected variable or a data frame of selected variables e.g. guerry[['Crm_prs', 'Literacy']] 20 | k (int): A positive integer number for k-nearest neighbors searching. 21 | scale_method (str, optional): One of the scaling methods {'raw', 'standardize', 'demean', 'mad', 'range_standardize', 'range_adjust'} to apply on input data. Default is 'standardize' (Z-score normalization). 22 | distance_method (str, optional): The type of distance metrics used to measure the distance between input data. Options are {'euclidean', 'manhattan'}. Default is 'euclidean'. 23 | power (float, optional): The power (or exponent) of a number says how many times to use the number in a multiplication. 24 | is_inverse (bool, optional): FALSE (default) or TRUE, apply inverse on distance value. 25 | is_arc (bool, optional): FALSE (default) or TRUE, compute arc distance between two observations. 26 | is_mile (bool, optional) TRUE (default) or FALSE, convert distance unit from mile to km. 27 | 28 | Returns: 29 | dict: A dict with values for key "Cardinality" and "Probability". 30 | ''' 31 | scale_method = 'standardize' if 'scale_method' not in kwargs else kwargs['scale_method'] 32 | distance_method = 'euclidean' if 'distance_method' not in kwargs else kwargs['distance_method'] 33 | power = 1.0 if 'power' not in kwargs else kwargs['power'] 34 | is_inverse = False if 'is_inverse' not in kwargs else kwargs['is_inverse'] 35 | is_arc = False if 'is_arc' not in kwargs else kwargs['is_arc'] 36 | is_mile = False if 'is_mile' not in kwargs else kwargs['is_mile'] 37 | 38 | if type(data).__name__ == "DataFrame": 39 | data = data.values.transpose().tolist() 40 | 41 | result = gda_neighbor_match_test(geoda_obj.gda, k, power, is_inverse, is_arc, is_mile, data, scale_method, distance_method) 42 | card = result[0] 43 | prob = result[1] 44 | 45 | new_card = [int(i) for i in card] 46 | # check p value 47 | new_prob = [p if p >= 0 else math.nan for p in prob] 48 | 49 | return { 50 | "Cardinality": new_card, 51 | "Probability": new_prob 52 | } 53 | -------------------------------------------------------------------------------- /pygeoda/sa/quantile_lisa.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_quantilelisa, gda_multiquantilelisa 2 | from ..libgeoda import VecBool, VecInt, VecVecDouble, VecVecBool, VecDouble 3 | from .lisa import lisa 4 | 5 | __author__ = "Xun Li , Hang Zhang " 6 | 7 | ''' 8 | Changes: 9 | 1/21/2021 update quantile_lisa; add multiquantile_lisa 10 | 2/11/2021 update local_quantilelisa, local_multiquantilelisa 11 | ''' 12 | 13 | def local_quantilelisa(w, data, k, q, **kwargs): 14 | """Quantile LISA Statistics 15 | The function to apply quantile LISA statistics 16 | 17 | Args: 18 | w (Weight): A spatial Weights object 19 | data (tuple/list/pandas.Series): A list of numeric values of selected variable 20 | k (int): The number of quantiles, range[1, n-1] 21 | q (int): The index of selected quantile for lisa, range[0, k-1] 22 | undefs (list, optional): A list of boolean values to indicate which value is undefined or null 23 | permutations (int, optional): The number of permutations for the LISA computation 24 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 25 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 26 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 27 | seed (int, optional): The seed for random number generator 28 | 29 | Returns: 30 | lisa: An instance of lisa class represents the results of quantile lisa 31 | """ 32 | if w == None: 33 | raise ValueError("Weights is None.") 34 | 35 | if data is None: 36 | raise ValueError("The data from selected variable is empty.") 37 | 38 | if k == None or k < 1: 39 | raise ValueError("The value of k needs to be greater than 1 ") 40 | 41 | if q == None or q < 0: 42 | raise ValueError("The value of q needs to be greater than 0") 43 | elif q > k: 44 | raise ValueError("The value of q needs to be smaller than or equal to k") 45 | 46 | undefs = VecBool() if 'undefs' not in kwargs else kwargs['undefs'] 47 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 48 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 49 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 50 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 51 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 52 | 53 | lisa_obj = gda_quantilelisa(w.gda_w, k, q, list(data), list(undefs), significance_cutoff, cpu_threads, permutations, permutation_method, seed) 54 | return lisa(lisa_obj) 55 | 56 | def local_multiquantilelisa(w, data, k, q, **kwargs): 57 | """Multivariate Quantile LISA Statistics 58 | The function to apply multivariate quantile LISA statistics 59 | 60 | Args: 61 | w (Weight): A spatial Weights object 62 | data (list or dataframe): A list of numeric vectors of selected variable or a data frame of selected variables e.g. guerry[['Crm_prs', 'Literacy']] 63 | k (tuple): A tuple of "k" (int) values indicate the number of quantiles for each variable 64 | q (tuple): A tuple of "q" (int) values indicate which quantile or interval for each variable used in local join count statistics 65 | permutations (int, optional): The number of permutations for the LISA computation 66 | permutation_method (str, optional): The permutation method used for the LISA computation. Options are {'complete', 'lookup-table'}. Default is 'complete'. 67 | significance_cutoff (float, optional): A cutoff value for significance p-values to filter not-significant clusters 68 | cpu_threads (int, optional): The number of cpu threads used for parallel LISA computation 69 | seed (int, optional): The seed for random number generator 70 | 71 | Returns: 72 | lisa: An instance of lisa class represents the results of quantile lisa 73 | """ 74 | 75 | undefs = VecVecBool() if 'undefs' not in kwargs else kwargs['undefs'] 76 | significance_cutoff = 0.05 if 'significance_cutoff' not in kwargs else kwargs['significance_cutoff'] 77 | permutations = 999 if 'permutations' not in kwargs else kwargs['permutations'] 78 | permutation_method = 'complete' if 'permutation_method' not in kwargs else kwargs['permutation_method'] 79 | cpu_threads = 6 if 'cpu_threads' not in kwargs else kwargs['cpu_threads'] 80 | seed = 123456789 if 'seed' not in kwargs else kwargs['seed'] 81 | 82 | if w == None: 83 | raise ValueError("Weights is None.") 84 | 85 | if len(data) == 0: 86 | raise ValueError("The input data can not be empty.") 87 | 88 | if len(data) != len(k) or len(k) != len(q): 89 | raise ValueError("The size of k, q and data are not matched.") 90 | 91 | if type(data).__name__ == "DataFrame": 92 | data = data.values.transpose().tolist() 93 | 94 | lisa_obj = gda_multiquantilelisa(w.gda_w, k, q, data, undefs, significance_cutoff, cpu_threads, permutations, permutation_method, seed) 95 | return lisa(lisa_obj) -------------------------------------------------------------------------------- /pygeoda/weights/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | A module for spatial weights 3 | """ 4 | from .queen import queen_weights 5 | from .rook import rook_weights 6 | from .distance import distance_weights, min_distthreshold, knn_weights 7 | from .kernel import kernel_weights, kernel_knn_weights 8 | from .weight import Weight, read_gal, read_gwt, read_swm -------------------------------------------------------------------------------- /pygeoda/weights/distance.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from ..libgeoda import gda_distance_weights, gda_min_distthreshold, gda_knn_weights 4 | from .weight import Weight 5 | 6 | def distance_weights(geoda_obj, dist_thres, **kwargs): 7 | '''Distance-based Spatial Weights 8 | Create a distance-based weights 9 | 10 | Args: 11 | geoda_obj (geoda): An instance of geoda class. 12 | dist_thres (float): A positive numeric value of distance threshold used to find neighbors. 13 | For example, one can use the pygeoda.min_distthreshold() to get a distance that 14 | guarantees that every observation has at least 1 neighbor. 15 | power (float, optional): The power (or exponent) of a number indicates how many times to use the number in a multiplication. 16 | is_inverse (bool, optional): A bool flag indicates whether or not to apply inverse on distance value. 17 | Defaults to False. 18 | is_arc (bool, optional): A bool flag indicates if compute arc distance or Euclidean distance. Defaults to False (Euclidean distance) 19 | is_mile (bool, optional): A bool flag indicates if the distance unit is mile or km. Defaults to True (mile). 20 | 21 | Returns: 22 | Weight: An instance of Weight class 23 | ''' 24 | power = 1.0 if 'power' not in kwargs else kwargs['power'] 25 | is_inverse = False if 'is_inverse' not in kwargs else kwargs['is_inverse'] 26 | is_arc = False if 'is_arc' not in kwargs else kwargs['is_arc'] 27 | is_mile = True if 'is_mile' not in kwargs else kwargs['is_mile'] 28 | 29 | poly_id = "" 30 | kernel = "" 31 | diagonal = False 32 | gda_w = gda_distance_weights(geoda_obj.gda, dist_thres, poly_id, power, is_inverse, is_arc, is_mile, kernel, diagonal) 33 | 34 | return Weight(gda_w) 35 | 36 | 37 | def min_distthreshold(geoda_obj, is_arc=False, is_mile=True): 38 | '''Minimum Distance Threshold for Distance-based Weights 39 | Get minimum threshold of distance that makes sure each observation has at least one neighbor 40 | 41 | Args: 42 | geoda_obj (geoda): An instance of geoda class. 43 | is_arc (bool, optional): A bool flag indicates if compute arc distance or Euclidean distance. Defaults to False (Euclidean distance) 44 | is_mile (bool, optional): A bool flag indicates if the distance unit is mile or km. Defaults to True (mile). 45 | 46 | Returns: 47 | thres (float): A float value of minimum threhold for distance based weights. 48 | ''' 49 | return gda_min_distthreshold(geoda_obj.gda, is_arc, is_mile) 50 | 51 | def knn_weights(geoda_obj, k, **kwargs): 52 | '''K-Nearest Neighbors-based Spatial Weights 53 | Create a k-nearest neighbors based spatial weights 54 | 55 | Args: 56 | geoda_obj (geoda): An instance of geoda class. 57 | k (int): A positive integer number for k-nearest neighbors 58 | power (float, optional): The power (or exponent) of a number indicates how many times to use the number in a multiplication. 59 | is_inverse (bool, optional): A bool flag indicates whether or not to apply inverse on distance value. 60 | Defaults to False. 61 | is_arc (bool, optional): A bool flag indicates if compute arc distance or Euclidean distance. Defaults to False (Euclidean distance) 62 | is_mile (bool, optional): A bool flag indicates if the distance unit is mile or km. Defaults to True (mile). 63 | 64 | 65 | Returns: 66 | Weight: An instance of Weight class 67 | ''' 68 | power = 1.0 if 'power' not in kwargs else kwargs['power'] 69 | is_inverse = False if 'is_inverse' not in kwargs else kwargs['is_inverse'] 70 | is_arc = False if 'is_arc' not in kwargs else kwargs['is_arc'] 71 | is_mile = True if 'is_mile' not in kwargs else kwargs['is_mile'] 72 | 73 | # not used 74 | kernel = "" 75 | bandwidth = 0 76 | adaptive_bandwidth = False 77 | use_kernel_diagnals = False 78 | polyid = "" 79 | 80 | gda_w = gda_knn_weights(geoda_obj.gda, k, power, is_inverse, is_arc, is_mile, kernel, bandwidth, adaptive_bandwidth, use_kernel_diagnals, polyid) 81 | 82 | return Weight(gda_w) -------------------------------------------------------------------------------- /pygeoda/weights/kernel.py: -------------------------------------------------------------------------------- 1 | __author__ = "Xun Li " 2 | 3 | from ..libgeoda import gda_distance_weights, gda_knn_weights 4 | from .weight import Weight 5 | 6 | def kernel_weights(geoda_obj, bandwidth, kernel, **kwargs): 7 | '''Distance-based Kernel Spatial Weights 8 | Create a kernel weights by specifying a bandwidth and a kernel method 9 | 10 | Args: 11 | geoda_obj (geoda): An instance of geoda class. 12 | bandwidth (float): A float value represents the distance of bandwidth used in kernel function. 13 | For example, one can use the pygeoda.min_distthreshold() to get a distance that 14 | guarantees that every observation has at least 1 neighbor. 15 | kernel (str): A string value, which has to be one of {'triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian'} 16 | use_kernel_diagonals (bool, optional): A bool flag indicates whether or not the lower order neighbors should be 17 | included in the weights structure. Defaults to False. 18 | is_inverse (bool, optional): A bool flag indicates whether or not to apply inverse on distance value. Defaults to False. 19 | power (float, optional): The power (or exponent) of a number indicates how many times to use the number in a multiplication. 20 | is_arc (bool, optional): A bool flag indicates if compute arc distance or Euclidean distance. Defaults to False (Euclidean distance) 21 | is_mile (bool, optional): A bool flag indicates if the distance unit is mile or km. Defaults to True (mile). 22 | 23 | Returns: 24 | Weight: An instance of Weight class 25 | ''' 26 | if kernel not in ['triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian']: 27 | raise("The parameter 'kernel' has to be one of {'triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian'}") 28 | 29 | use_kernel_diagonals = False if 'use_kernel_diagonals' not in kwargs else kwargs['use_kernel_diagonals'] 30 | is_arc = False if 'is_arc' not in kwargs else kwargs['is_arc'] 31 | is_mile = True if 'is_mile' not in kwargs else kwargs['is_mile'] 32 | power = 1.0 if 'power' not in kwargs else kwargs['power'] 33 | is_inverse = False if 'is_inverse' not in kwargs else kwargs['is_inverse'] 34 | 35 | poly_id = "" 36 | 37 | gda_w = gda_distance_weights(geoda_obj.gda, bandwidth, poly_id, power, is_inverse, is_arc, is_mile, kernel, use_kernel_diagonals) 38 | 39 | return Weight(gda_w) 40 | 41 | 42 | def kernel_knn_weights(geoda_obj, k, kernel, **kwargs): 43 | '''K-NN Kernel Spatial Weights 44 | Create a kernel weights by specifying k-nearest neighbors and a kernel method 45 | 46 | Args: 47 | geoda_obj (geoda): An instance of geoda class. 48 | k (int): a positive integer number for k-nearest neighbors 49 | kernel (str): A string value, which has to be one of {'triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian'} 50 | Adaptive_bandwidth (bool, optional): True(default) or False: True - use adaptive bandwidth calculated using distance of k-nearest neithbors, False - use max distance of all observation to their k-nearest neighbors 51 | use_kernel_diagonals (bool, optional): A bool flag indicates whether or not the lower order neighbors should be 52 | included in the weights structure. Defaults to False. 53 | is_inverse (bool, optional): A bool flag indicates whether or not to apply inverse on distance value. Defaults to False. 54 | power (float, optional): The power (or exponent) of a number indicates how many times to use the number in a multiplication. 55 | is_arc (bool, optional): A bool flag indicates if compute arc distance or Euclidean distance. Defaults to False (Euclidean distance) 56 | is_mile (bool, optional): A bool flag indicates if the distance unit is mile or km. Defaults to True (mile). 57 | 58 | Returns: 59 | Weight: An instance of Weight class 60 | ''' 61 | if kernel not in ['triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian']: 62 | raise("The parameter 'kernel' has to be one of 'triangular', 'uniform', 'epanechnikov', 'quartic', 'gaussian'") 63 | 64 | adaptive_bandwidth = True if 'adaptive_bandwidth' not in kwargs else kwargs['adaptive_bandwidth'] 65 | use_kernel_diagonals = False if 'use_kernel_diagonals' not in kwargs else kwargs['use_kernel_diagonals'] 66 | power = 1.0 if 'power' not in kwargs else kwargs['power'] 67 | is_inverse = False if 'is_inverse' not in kwargs else kwargs['is_inverse'] 68 | is_arc = False if 'is_arc' not in kwargs else kwargs['is_arc'] 69 | is_mile = True if 'is_mile' not in kwargs else kwargs['is_mile'] 70 | bandwidth = 0 71 | polyid = "" 72 | 73 | gda_w = gda_knn_weights(geoda_obj.gda, k, power, is_inverse, is_arc, is_mile, kernel, bandwidth, adaptive_bandwidth, use_kernel_diagonals, polyid) 74 | 75 | return Weight(gda_w) -------------------------------------------------------------------------------- /pygeoda/weights/queen.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_queen_weights 2 | from .weight import Weight 3 | 4 | __author__ = "Xun Li " 5 | 6 | def queen_weights(geoda_obj, **kwargs): 7 | """Queen Contiguity Spatial Weights 8 | Create a Queen contiguity weights with options of "order", "include lower order" and "precision threshold" 9 | 10 | Args: 11 | geoda_obj (geoda): An instance of Geoda object 12 | order (int, optional): An integer value of order of contiguity 13 | include_lower_order (bool, optional): A bool flag indicates whether or not the lower order neighbors should be 14 | included in the weights structure. Defaults to False. 15 | precision_threshold (float, optional): A float value represents the precision of the underlying shape file is insufficient 16 | to allow for an exact match of coordinates to determine 17 | which polygons are neighbors. Defaults to 0.0. 18 | 19 | Returns: 20 | Weight: An instance of Weight class 21 | """ 22 | order = 1 if 'order' not in kwargs else kwargs['order'] 23 | include_lower_order = False if 'include_lower_order' not in kwargs else kwargs['include_lower_order'] 24 | precision_threshold = 0.0 if 'precision_threshold' not in kwargs else kwargs['precision_threshold'] 25 | 26 | gda_w = gda_queen_weights(geoda_obj.gda, order, include_lower_order, precision_threshold) 27 | 28 | return Weight(gda_w) 29 | 30 | -------------------------------------------------------------------------------- /pygeoda/weights/rook.py: -------------------------------------------------------------------------------- 1 | from ..libgeoda import gda_rook_weights 2 | from .weight import Weight 3 | 4 | __author__ = "Xun Li " 5 | 6 | def rook_weights(geoda_obj, **kwargs): 7 | '''Rook Contiguity Spatial Weights 8 | Create a Rook contiguity weights with options of "order", "include lower order" and "precision threshold" 9 | 10 | Args: 11 | geoda_obj (geoda): An instance of geoda class 12 | order (int, optional): order of contiguity 13 | include_lower_order (bool, optional): whether or not the lower order neighbors should be 14 | included in the weights structure 15 | precision_threshold (float, optional): the precision of the underlying shape file is insufficient 16 | to allow for an exact match of coordinates to determine 17 | which polygons are neighbors 18 | 19 | Returns: 20 | Weight: An instance of Weight object 21 | ''' 22 | order = 1 if 'order' not in kwargs else kwargs['order'] 23 | include_lower_order = False if 'include_lower_order' not in kwargs else kwargs['include_lower_order'] 24 | precision_threshold = 0.0 if 'precision_threshold' not in kwargs else kwargs['precision_threshold'] 25 | 26 | gda_w = gda_rook_weights(geoda_obj.gda, order, include_lower_order, precision_threshold) 27 | 28 | return Weight(gda_w) 29 | 30 | -------------------------------------------------------------------------------- /swig.sh: -------------------------------------------------------------------------------- 1 | swig -python -c++ -threads -I./libgeoda -o ./pygeoda/libgeoda.cpp ./libgeoda.i -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | if [[ "$OSTYPE" == "linux-gnu" ]]; then 2 | python setup.py build_ext --inplace --force 3 | elif [[ "$OSTYPE" == "darwin"* ]]; then 4 | python3 setup.py build_ext --inplace --force 5 | #python3 setup.py build_ext --inplace --force 6 | mv pygeoda/_libgeoda.*.so pygeoda/_libgeoda.so 7 | elif [[ "$OSTYPE" == "cygwin" ]]; then 8 | echo "POSIX compatibility layer and Linux environment emulation for Windows" 9 | elif [[ "$OSTYPE" == "msys" ]]; then 10 | echo "Lightweight shell and GNU utilities compiled for Windows (part of MinGW)" 11 | elif [[ "$OSTYPE" == "win32" ]]; then 12 | echo "I'm not sure this can happen." 13 | elif [[ "$OSTYPE" == "freebsd"* ]]; then 14 | echo "freebsd" 15 | else 16 | echo "Unknown." 17 | fi 18 | 19 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeoDaCenter/pygeoda/72b5ff10db0fd806ff0cb65bd8448df7f4a2c1a0/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_classify.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pygeoda 3 | 4 | __author__ = "Xun Li , Hang Zhang , " 5 | 6 | class TestClassify(unittest.TestCase): 7 | def setUp(self): 8 | self.guerry = pygeoda.open("./data/Guerry.shp") 9 | self.crm_prp = self.guerry.GetIntegerCol("Crm_prp") 10 | 11 | def test_hinge15_breaks(self): 12 | breaks = pygeoda.hinge15_breaks(self.crm_prp) 13 | 14 | self.assertAlmostEqual(len(breaks),5) 15 | self.assertAlmostEqual(breaks,(1190.0, 5990.0, 7624.0, 9190.0, 13990.0)) 16 | 17 | def test_hinge30_breaks(self): 18 | breaks = pygeoda.hinge30_breaks(self.crm_prp) 19 | 20 | self.assertAlmostEqual(len(breaks),5) 21 | self.assertAlmostEqual(breaks,(-3610.0, 5990.0, 7624.0, 9190.0, 18790.0)) 22 | 23 | def test_natural_breaks(self): 24 | breaks = pygeoda.natural_breaks(5, self.crm_prp) 25 | 26 | self.assertAlmostEqual(len(breaks),4) 27 | self.assertAlmostEqual(breaks,(5521.0, 7204.0, 10237.0, 15890.0)) 28 | 29 | def test_quantile_breaks(self): 30 | breaks = pygeoda.quantile_breaks(5,self.crm_prp) 31 | 32 | self.assertAlmostEqual(len(breaks),4) 33 | self.assertAlmostEqual(breaks,(5439.0, 6886.0, 8205.0, 9584.5)) 34 | 35 | def test_percentile_breaks(self): 36 | breaks = pygeoda.percentile_breaks(self.crm_prp) 37 | 38 | self.assertAlmostEqual(len(breaks),5) 39 | self.assertAlmostEqual(breaks,(1906.3, 4529.0, 7624.0, 10954.0, 19467.800000000003)) 40 | 41 | def test_stddev_breaks(self): 42 | breaks = pygeoda.stddev_breaks(self.crm_prp) 43 | 44 | self.assertEqual(len(breaks), 5) 45 | self.assertAlmostEqual(breaks, (1784.1106064421238, 4832.725891456355, 7881.341176470588, 10929.95646148482, 13978.571746499052)) 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/test_data.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pygeoda 3 | 4 | __author__ = "Xun Li , Hang Zhang , " 5 | 6 | class TestTransform(unittest.TestCase): 7 | def setUp(self): 8 | self.guerry = pygeoda.open("./data/Guerry.shp") 9 | self.queen_w = pygeoda.queen_weights(self.guerry) 10 | select_vars = ["Crm_prs", "Crm_prp", "Litercy", "Donatns", "Infants", "Suicids"] 11 | self.data = [self.guerry.GetRealCol(v) for v in select_vars] 12 | self.Crm_prs = self.guerry.GetRealCol('Crm_prs') 13 | self.Crm_prp = self.guerry.GetRealCol('Crm_prp') 14 | 15 | def test_DEMEAN(self): 16 | results = pygeoda.demean(self.data) 17 | self.assertAlmostEqual(results[0][0], 8909.058823529413) 18 | self.assertAlmostEqual(results[1][0], 8008.658823529412) 19 | self.assertAlmostEqual(results[2][0], -2.141176470588235) 20 | self.assertAlmostEqual(results[3][0], -1625.3176470588232) 21 | self.assertAlmostEqual(results[4][0], 14137.070588235296) 22 | self.assertAlmostEqual(results[5][0], -1477.800000000003) 23 | 24 | def test_STANDARDIZE(self): 25 | results = pygeoda.standardize(self.data) 26 | self.assertAlmostEqual(results[0][0], 1.220545786363259) 27 | self.assertAlmostEqual(results[1][0], 2.626982441141971) 28 | self.assertAlmostEqual(results[2][0], -0.12281377647044796) 29 | self.assertAlmostEqual(results[3][0], -0.3342044000744191) 30 | self.assertAlmostEqual(results[4][0], 1.5973093769164821) 31 | self.assertAlmostEqual(results[5][0], -0.04691678974541437) 32 | 33 | def test_MAD(self): 34 | results = pygeoda.mad(self.data) 35 | self.assertAlmostEqual(results[0][0], 1.4834982357401478) 36 | self.assertAlmostEqual(results[1][0], 3.657995001677823) 37 | self.assertAlmostEqual(results[2][0], -0.14598471265452484) 38 | self.assertAlmostEqual(results[3][0], -0.43856444476347173) 39 | self.assertAlmostEqual(results[4][0], 2.288114647653677) 40 | self.assertAlmostEqual(results[5][0], -0.06627296020171916) -------------------------------------------------------------------------------- /tests/test_weights.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pygeoda 3 | 4 | __author__ = "Xun Li , " 5 | 6 | class TestWeights(unittest.TestCase): 7 | def setUp(self): 8 | self.nat = pygeoda.open("./data/natregimes.shp") 9 | self.poly_id = self.nat.GetIntegerCol("POLY_ID") 10 | 11 | def test_queen_weights(self): 12 | w = pygeoda.queen_weights(self.nat) 13 | 14 | self.assertEqual(w.num_obs, 3085) 15 | self.assertEqual(w.min_neighbors(), 1) 16 | self.assertEqual(w.mean_neighbors(), 5.8891410048622364) 17 | self.assertEqual(w.max_neighbors(), 14) 18 | self.assertTrue(w.is_symmetric()) 19 | self.assertAlmostEqual(w.weights_sparsity(), 0.0019089598070866245) 20 | 21 | def test_queen2_weight(self): 22 | 23 | w = pygeoda.queen_weights(self.nat,order = 2, include_lower_order = True, precision_threshold = 1.0) 24 | 25 | self.assertEqual(w.num_obs, 3085) 26 | self.assertEqual(w.min_neighbors(), 2) 27 | self.assertEqual(w.mean_neighbors(), 18.574392220421394) 28 | self.assertEqual(w.max_neighbors(), 40) 29 | self.assertTrue(w.is_symmetric()) 30 | self.assertAlmostEqual(w.weights_sparsity(), 0.006020872680849723) 31 | 32 | def test_rook_weights(self): 33 | w = pygeoda.rook_weights(self.nat) 34 | 35 | self.assertEqual(w.num_obs, 3085) 36 | self.assertEqual(w.min_neighbors(), 1) 37 | self.assertEqual(w.mean_neighbors(), 5.571474878444084) 38 | self.assertEqual(w.max_neighbors(), 13) 39 | self.assertTrue(w.is_symmetric()) 40 | self.assertAlmostEqual(w.weights_sparsity(), 0.0018059886153789576) 41 | 42 | def test_rook2_weights(self): 43 | w = pygeoda.rook_weights(self.nat, order=2, include_lower_order = True, precision_threshold = 2.0) 44 | 45 | self.assertEqual(w.num_obs, 3085) 46 | self.assertEqual(w.min_neighbors(), 2) 47 | self.assertEqual(w.mean_neighbors(), 18.574392220421394) 48 | self.assertEqual(w.max_neighbors(), 40) 49 | self.assertTrue(w.is_symmetric()) 50 | self.assertAlmostEqual(w.weights_sparsity(), 0.006020872680849723) 51 | 52 | def test_knn_weights(self): 53 | k = 4 54 | w = pygeoda.knn_weights(self.nat, k, power=2.0) 55 | 56 | self.assertEqual(w.num_obs, 3085) 57 | self.assertEqual(w.min_neighbors(), 4) 58 | self.assertEqual(w.mean_neighbors(), 4) 59 | self.assertEqual(w.max_neighbors(), 4) 60 | self.assertFalse(w.is_symmetric()) 61 | self.assertAlmostEqual(w.weights_sparsity(), 0.0012965964343598055) 62 | 63 | def test_knn2_weights(self): 64 | k = 6 65 | w = pygeoda.knn_weights(self.nat, k, power = 2.0, is_inverse = True, is_arc = True, is_mile = False) 66 | 67 | self.assertEqual(w.num_obs, 3085) 68 | self.assertEqual(w.min_neighbors(), 6) 69 | self.assertEqual(w.mean_neighbors(), 6.00) 70 | self.assertEqual(w.max_neighbors(), 6) 71 | self.assertFalse(w.is_symmetric()) 72 | self.assertAlmostEqual(w.weights_sparsity(), 0.0019448946515397084) 73 | 74 | 75 | def test_distance_threshold_weights(self): 76 | dist_thres = pygeoda.min_distthreshold(self.nat) 77 | w = pygeoda.distance_weights(self.nat, dist_thres) 78 | 79 | self.assertEqual(dist_thres, 1.4657759325950015) 80 | self.assertEqual(w.num_obs, 3085) 81 | self.assertEqual(w.min_neighbors(), 1) 82 | self.assertEqual(w.mean_neighbors(), 36.833711507293351) 83 | self.assertEqual(w.max_neighbors(), 85) 84 | self.assertTrue(w.is_symmetric()) 85 | self.assertEqual(w.weights_sparsity(), 0.011939614751148575) 86 | 87 | def test_distance2_threshold_weights(self): 88 | dist_thres = pygeoda.min_distthreshold(self.nat) 89 | w = pygeoda.distance_weights(self.nat, dist_thres, power = 2.0, is_inverse = True) 90 | 91 | self.assertEqual(dist_thres, 1.4657759325950015) 92 | self.assertEqual(w.num_obs, 3085) 93 | self.assertEqual(w.min_neighbors(), 1) 94 | self.assertEqual(w.mean_neighbors(), 36.83371150729335) 95 | self.assertEqual(w.max_neighbors(), 85) 96 | self.assertTrue(w.is_symmetric()) 97 | self.assertEqual(w.weights_sparsity(), 0.011939614751148575) 98 | 99 | def test_kernel_knn_weights(self): 100 | k = 15 101 | kernel = "triangular" 102 | w = pygeoda.kernel_knn_weights(self.nat, k, kernel) 103 | 104 | self.assertEqual(w.num_obs, 3085) 105 | self.assertEqual(w.min_neighbors(), 15) 106 | self.assertEqual(w.mean_neighbors(), 15) 107 | self.assertEqual(w.max_neighbors(), 15) 108 | self.assertFalse(w.is_symmetric()) 109 | self.assertEqual(w.weights_sparsity(), 0.0048622366288492708) 110 | 111 | def test_kernel2_knn_weights(self): 112 | k = 12 113 | kernel = "gaussian" 114 | w = pygeoda.kernel_knn_weights(self.nat, k, kernel, use_kernel_diagonals = True) 115 | 116 | self.assertEqual(w.num_obs, 3085) 117 | self.assertEqual(w.min_neighbors(), 12) 118 | self.assertEqual(w.mean_neighbors(), 12) 119 | self.assertEqual(w.max_neighbors(), 12) 120 | self.assertFalse(w.is_symmetric()) 121 | self.assertAlmostEqual(w.weights_sparsity(), 0.0038897893030) 122 | 123 | def test_kernel_distband_weights(self): 124 | bandwidth = pygeoda.min_distthreshold(self.nat) 125 | kernel = "triangular" 126 | w = pygeoda.kernel_weights(self.nat, bandwidth, kernel) 127 | 128 | self.assertEqual(bandwidth, 1.4657759325950015) 129 | self.assertEqual(w.num_obs, 3085) 130 | self.assertEqual(w.min_neighbors(), 1) 131 | self.assertEqual(w.mean_neighbors(), 36.83371150729335) 132 | self.assertEqual(w.max_neighbors(), 85) 133 | self.assertFalse(w.is_symmetric()) 134 | self.assertEqual(w.weights_sparsity(), 0.011939614751148575) 135 | 136 | def test_kernel2_distband_weights(self): 137 | bandwidth = pygeoda.min_distthreshold(self.nat) 138 | kernel = "quartic" 139 | w = pygeoda.kernel_weights(self.nat, bandwidth, kernel, use_kernel_diagonals = True) 140 | 141 | self.assertEqual(bandwidth, 1.4657759325950015) 142 | self.assertEqual(w.num_obs, 3085) 143 | self.assertEqual(w.min_neighbors(), 1) 144 | self.assertEqual(w.mean_neighbors(), 36.83371150729335) 145 | self.assertEqual(w.max_neighbors(), 85) 146 | self.assertFalse(w.is_symmetric()) 147 | self.assertEqual(w.weights_sparsity(), 0.011939614751148575) 148 | 149 | 150 | """ 151 | def test_SaveToFile(self): 152 | w = pygeoda.queen_weights(self.nat) 153 | w.SaveToFile('D:/ttt/','natregimes.shp','POLY_ID',self.nat.GetIntegerCol("POLY_ID")) 154 | """ --------------------------------------------------------------------------------