Repository: mthh/jenkspy Branch: master Commit: e4f6356340d8 Files: 15 Total size: 114.7 KB Directory structure: gitextract_i4o0czsk/ ├── .github/ │ └── workflows/ │ └── wheel.yml ├── .gitignore ├── CHANGES.rst ├── LICENSE ├── MANIFEST.in ├── README.md ├── jenkspy/ │ ├── __init__.py │ ├── core.py │ └── src/ │ ├── _jenks.c │ └── jenks.pyx ├── pyproject.toml ├── setup.py └── tests/ ├── __init__.py ├── test.json └── test_jenks.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/wheel.yml ================================================ name: Build on: [push, pull_request, workflow_dispatch] jobs: build_wheels: name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: ["macos-latest", "ubuntu-latest", "windows-latest"] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 - name: "Build wheels" uses: pypa/cibuildwheel@v3.3.1 with: package-dir: . env: CIBW_BEFORE_BUILD: pip install numpy cython CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 CIBW_SKIP: "*musllinux*" CIBW_ARCHS_LINUX: "x86_64" CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ARCHS_WINDOWS: "AMD64" CIBW_TEST_SKIP: "*_arm64" CIBW_TEST_COMMAND: python {package}/tests/test_jenks.py - uses: actions/upload-artifact@v4 with: path: ./wheelhouse/*.whl name: artifacts-${{ matrix.os }} ================================================ FILE: .gitignore ================================================ # Manifest generated by distutils MANIFEST # Cython generated C file jenkspy/src/jenks.c # Editor .vscode/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # IPython Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # dotenv .env # virtualenv venv*/ venv/ ENV/ # Spyder project settings .spyderproject # Rope project settings .ropeproject # Wheels wheelhouse/ # JetBrains IDEA folder .idea/ ================================================ FILE: CHANGES.rst ================================================ Changes ======= 0.4.1 (2024-06-03) ------------------ - Introduce pyproject.toml to replace the old way of describing the project and specifying build dependencies, thanks to @filip-komarzyniec (see PR #31). 0.4.0 (2023-11-30) ------------------ - Add support for Python 3.12. - Don't track the C file generated by Cython anymore. 0.3.3 (2023-07-03) ------------------ - Fix error when JenksNaturalBreaks is instanced with n_classes=1 and raise error if n_classes is not a positive integer (fix #28). 0.3.2 (2022-11-10) ------------------ - Add type hints and fix some docstring about parameters and return types, thanks to Kim Hyeonseok / @plming (#27). 0.3.1 (2022-08-23) ------------------ - Add missing requirements.txt file in MANIFEST.in and in sdist package. 0.3.0 (2022-08-23) ------------------ - Add NumPy as a mandatory dependency. - Only compute matrices in C code and move sorting the values, casting to double, and computing the actual breaks to Python/Cython code for better maintainability. - Improve performance by using 1D arrays instead of 2D arrays in ``JenksBreakValues`` C function. - Preserve the precision of the original list/array of values in the returned breaks. - Fix bug when requesting a number of class equal to the number of values. - Raise an exception when the number of classes is greater than the number of unique values (however this might change in the future by choosing to return a list of breaks shorter than the one requested by the user). - Rename ``nb_class`` parameter to ``n_classes`` (notably to be closer to sklearn ``n_clusters`` parameter). 0.2.4 (2022-08-18) ------------------ - Update package metadata and docstrings. 0.2.3 (2022-08-18) ------------------ - Check size of integer values given to ``jenks_breaks`` function to avoid Segfault when casting to C double (fixes #23). - Raise an error (instead of printing a warning) when target array contains non-finite values (fixes #23). - Raise an error when the target numpy.ndarray is not one-dimensional (fixes #25). - Improve implementation of ``JenksBreakValues`` C function by using better variable naming and by simplifying the construction of the 'breaks' array (should partly fix #22). - Add docstrings to ``JenksNaturalBreaks`` methods. 0.2.2 (2022-08-12) ------------------ - Update docstring to fix return type of ``jenks_breaks`` (fix #26). 0.2.1 (2022-08-12) ------------------ - Add a method to the ``JenksNaturalBreaks`` class that calculates the Goodness of Fit Variance thanks to Maurício Gomes / @mgomesq (#17). - Add optional download numpy using ``[interface]`` thanks to Muhammad Yasirroni / @yasirroni (#16). - Replace Travis / AppVeyor by GitHub Actions to build wheels for currently supported python versions on Windows / MacOs / Linux (according to https://devguide.python.org/versions/#supported-versions) 0.2.0 (2020-10-18) ------------------ - Add ``JenksNaturalBreaks`` for computing breaks in a more object-oriented manner, with an interface similar to those provided by scikit-learn *(requires Numpy to take full advantage of it)* (thanks to @yasirroni, #11) 0.1.6 (2020-09-02) ------------------ - Removes support for Python2 (simplifies some minor parts of the code) and add Python 3.8 to the appveyor matrix. - Updates docstrings and README to clarify that the result includes the lower and upper value. 0.1.5 (2018-11-15) ------------------ - Fix segfault occurring when the input array was containing NaN or Inf values (#4). - Create this changelog. ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2016-2022 Matthieu Viry Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ graft tests ================================================ FILE: README.md ================================================ # Jenkspy: Fast Fisher-Jenks breaks for Python Compute "natural breaks" (*Fisher-Jenks algorithm*) on list / tuple / array / numpy.ndarray of integers/floats. The algorithm implemented by this library is also sometimes referred to as *Fisher-Jenks algorithm*, *Jenks Optimisation Method* or *Fisher exact optimization method*. This is a deterministic method to calculate the optimal class boundaries. Intended compatibility: CPython 3.8+ Wheels are provided via PyPI for Windows / MacOS / Linux users - Also available on conda-forge channel for Anaconda users. [![](https://github.com/mthh/jenkspy/actions/workflows/wheel.yml/badge.svg)](https://github.com/mthh/jenkspy/actions/workflows/wheel.yml) [![](https://img.shields.io/pypi/v/jenkspy.svg?color=007ec6)](https://pypi.python.org/pypi/jenkspy) [![](https://anaconda.org/conda-forge/jenkspy/badges/version.svg)](https://anaconda.org/conda-forge/jenkspy) [![](https://img.shields.io/pypi/dm/jenkspy.svg)](https://pypi.python.org/pypi/jenkspy) ## Usage Two ways of using `jenkspy` are available: - by using the `jenks_breaks` function which takes as input a [`list`](https://docs.python.org/3/library/stdtypes.html#list) / [`tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) / [`array.array`](https://docs.python.org/3/library/array.html#array.array) / [`numpy.ndarray`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) of integers or floats and returns a list of values that correspond to the limits of the classes (starting with the minimum value of the series - the lower bound of the first class - and ending with its maximum value - the upper bound of the last class). ```python >>> import jenkspy >>> import json >>> with open('tests/test.json', 'r') as f: ... # Read some data from a JSON file ... data = json.loads(f.read()) ... >>> jenkspy.jenks_breaks(data, n_classes=5) # Asking for 5 classes [0.0028109620325267315, 2.0935479691252112, 4.205495140049607, 6.178148351609707, 8.09175917180255, 9.997982932254672] # ^ ^ ^ ^ ^ ^ # Lower bound Upper bound Upper bound Upper bound Upper bound Upper bound # 1st class 1st class 2nd class 3rd class 4th class 5th class # (Minimum value) (Maximum value) ``` - by using the `JenksNaturalBreaks` class that is inspired by `scikit-learn` classes. The `.fit` and `.group` behavior is slightly different from `jenks_breaks`, by accepting value outside the range of the minimum and maximum value of `breaks_`, retaining the input size. It means that fit and group will use only the `inner_breaks_`. All value below the min bound will be included in the first group and all value higher than the max bound will be included in the last group. ```python >>> from jenkspy import JenksNaturalBreaks >>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] >>> jnb = JenksNaturalBreaks(4) # Asking for 4 clusters >>> jnb.fit(x) # Create the clusters according to values in 'x' >>> print(jnb.labels_) # Labels for fitted data ... print(jnb.groups_) # Content of each group ... print(jnb.breaks_) # Break values (including min and max) ... print(jnb.inner_breaks_) # Inner breaks (ie breaks_[1:-1]) [0 0 0 1 1 1 2 2 2 3 3 3] [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])] [0.0, 2.0, 5.0, 8.0, 11.0] [2.0, 5.0, 8.0] >>> print(jnb.predict(15)) # Predict the group of a value 3 >>> print(jnb.predict([2.5, 3.5, 6.5])) # Predict the group of several values [1 1 2] >>> print(jnb.group([2.5, 3.5, 6.5])) # Group the elements into there groups [array([], dtype=float64), array([2.5, 3.5]), array([6.5]), array([], dtype=float64)] ``` ## Installation - **From pypi** ```shell pip install jenkspy ``` - **From source** ```shell git clone http://github.com/mthh/jenkspy cd jenkspy/ pip install . ``` - **For anaconda users** ```shell conda install -c conda-forge jenkspy ``` ## Requirements - [Numpy](https://numpy.org) - Only for building from source: C compiler, Python C headers, setuptools and Cython. ## Motivation: - Making a painless installing C extension so it could be used more easily as a dependency in an other package (and so learning how to build wheels using *appveyor* / *travis* at first - now it uses *GitHub Actions*). - Getting the break values! (and fast!). No fancy functionality provided, but contributions/forks/etc are welcome. - Other python implementations are currently existing but not as fast or not available on PyPi. ================================================ FILE: jenkspy/__init__.py ================================================ #!/usr/bin/env python # -*- coding: utf-8 -*- __version__ = "0.4.1" from .core import jenks_breaks from .core import _jenks_matrices from .core import JenksNaturalBreaks __all__ = ['jenks_breaks', '_jenks_matrices', 'JenksNaturalBreaks'] ================================================ FILE: jenkspy/core.py ================================================ # -*- coding: utf-8 -*- import numpy as np from collections.abc import Iterable as IterableType from typing import List, Dict, Union, Iterable, Sequence from . import jenks class JenksNaturalBreaks: """ A class that can be used to classify a sequence of numbers into groups (clusters) using Fisher-Jenks natural breaks. """ def __init__(self, n_classes: int = 6) -> None: """ Parameters ---------- n_classes : int The number of classes to be generated by the classifier (should be a positive integer). """ if isinstance(n_classes, float) and int(n_classes) == n_classes: n_classes = int(n_classes) if not isinstance(n_classes, int): raise TypeError( "Number of class have to be a positive integer: " "expected an instance of 'int' but found {}" .format(type(n_classes))) if n_classes < 1: raise ValueError( "Number of class have to be an integer " "greater than or equal to 1" ) self.n_classes = n_classes def __repr__(self) -> str: return f"JenksNaturalBreaks(n_classes={self.n_classes})" def __str__(self) -> str: return f"JenksNaturalBreaks(n_classes={self.n_classes})" def fit(self, x: Sequence[float]) -> None: """ Parameters ---------- x : array-like The sequence of numbers (integer/float) to be classified. """ self.breaks_ = jenks_breaks(x, self.n_classes) self.inner_breaks_ = self.breaks_[1:-1] # because inner_breaks is more self.labels_ = self.predict(x) self.groups_ = self.group(x) def predict(self, x: Union[float, Iterable[float]]) -> np.ndarray: """ Predicts the class of each element in x. Parameters ---------- x : scalar or array-like Returns ------- numpy.array """ if not isinstance(x, IterableType): return np.array(self.get_label_(x, idx=0)) labels_ = [] for val in x: label_ = self.get_label_(val, idx=0) labels_.append(label_) return np.array(labels_) def group(self, x: Sequence[float]) -> List[np.ndarray]: """ Groups the elements in x into groups according to the classifier. Parameters ---------- x : array-like The sequence of numbers (integer/float) to be classified. Returns ------- list of numpy.array The list of groups that contains the values of x. """ if self.n_classes == 1: return [np.array(x)] arr = np.array(x) groups_ = [arr[arr <= self.inner_breaks_[0]]] for idx in range(len(self.inner_breaks_))[:-1]: groups_.append(arr[(arr > self.inner_breaks_[idx])*(arr <= self.inner_breaks_[idx + 1])]) groups_.append(arr[arr > self.inner_breaks_[-1]]) return groups_ def goodness_of_variance_fit(self, x: Sequence[float]) -> float: """ Parameters ---------- x : array-like Returns ------- float The goodness of variance fit. """ arr = np.array(x) array_mean = np.mean(arr) sdam = sum([(value - array_mean) ** 2 for value in arr]) sdcm = 0 for group in self.groups_: group_mean = np.mean(group) sdcm += sum([(value - group_mean) ** 2 for value in group]) gvf = (sdam - sdcm)/sdam return gvf def get_label_(self, val: float, idx: int = 0) -> int: """ Compute the group label of the given value. Parameters ---------- val : float The value to be classified. idx : int, optional Returns ------- int : The label of the value. """ try: if val <= self.inner_breaks_[idx]: return idx else: idx = self.get_label_(val, idx + 1) return idx except: return len(self.inner_breaks_) def validate_input(values: Sequence[float], n_classes: int) -> int: # Check input so that we have a sequence of numbers if not isinstance(values, IterableType) or isinstance(values, (str, bytes)): raise TypeError("A sequence of numbers is expected") # Number of classes have to be an integer if isinstance(n_classes, float) and int(n_classes) == n_classes: n_classes = int(n_classes) if not isinstance(n_classes, int): raise TypeError( "Number of class have to be a positive integer: " "expected an instance of 'int' but found {}" .format(type(n_classes))) # Check that numpy arrays are 1-dimensional if isinstance(values, np.ndarray): if len(values.shape) != 1: raise ValueError("A 1D array is expected") # Check that all values are finite (and can be cast safely to double later) try: if not np.isfinite(values).all(): raise ValueError("All values have to be finite") except TypeError as e: import sys _, value, traceback = sys.exc_info() raise TypeError( "The sequence of values contains values that will overflow C double capacities - %s" .format(value) ).with_traceback(traceback) # Check that the number of classes is lesser than or equal to the length of unique values # and greater than or equal to 1 if n_classes > len(np.unique(values)) or n_classes < 1: raise ValueError("Number of class have to be an integer greater than or equal to 1 and " "smaller than or equal to the number of unique values to use") return n_classes def jenks_breaks(values: Sequence[float], n_classes: int) -> List[float]: """ Compute natural breaks (Fisher-Jenks algorithm) on a sequence of `values`, given `n_classes`, the number of desired class. Parameters ---------- values : array-like The sequence of numbers (integer/float) to be used. n_classes : int The desired number of class. Have to be lesser than or equal to the length of `values` and greater than or equal to 1. Returns ------- breaks : list of floats The computed break values, including minimum and maximum, in order to have all the bounds for building `n_classes` classes, so the returned list has a length of `n_classes` + 1. Examples -------- Using n_classes = 3, expecting 4 break values , including min and max : >>> jenks_breaks( [1.3, 7.1, 7.3, 2.3, 3.9, 4.1, 7.8, 1.2, 4.3, 7.3, 5.0, 4.3], n_classes = 3) # Should output [1.2, 2.3, 5.0, 7.8] """ n_classes = validate_input(values, n_classes) return jenks._jenks_breaks(values, n_classes) def _jenks_matrices(values: Sequence[float], n_classes: int, testing_algo: bool = False) -> Dict[str, np.ndarray]: """ Returns the intermediate matrices (lower_class_limits and variance combinations) that are created when computing natural breaks (Fisher-Jenks algorithm) on a sequence of `values`, given `n_classes`, the number of desired class. This is only used for testing and debugging purpose, it is not part of the supported API and might disappear at any time. Parameters ---------- values : array-like The sequence of numbers (integer/float) to be used. n_classes : int The desired number of class. Have to be lesser than or equal to the length of `values` and greater than or equal to 1. testing_algo : bool If False, use the 'normal' version of the algorithm to compute the matrices, if True, use the version of the algorithm that mimic Fortran implementation by using the same indexing. Returns ------- dict : The computed matrices, as numpy arrays, in a dict with keys 'lower_class_limits' and 'variance_combinations'. """ n_classes = validate_input(values, n_classes) if testing_algo not in (True, False): raise ValueError('testing_algo parameters have to be either True or False') return jenks._jenks_matrices(values, n_classes, testing_algo) ================================================ FILE: jenkspy/src/_jenks.c ================================================ #include #include #include // Macro to access the elements of our matrices #define IX(i,j) (i)*(width)+(j) // Compute FisherJenks matrices. // Compared to fish.f code, some arithmetic might seem // a little different but this is because we use C arrays whose values start at 0 // and not Fortran arrays (and also because most other implementations // at the time of writing (in Python, JS, etc.) // don't take care to simplify these calculations). // See also the comments below about this. // ---------------------------------------------------------------------------- // Parameters: // variance_combinations: array of length 'length_array' * 'n_classes' (modified) // lower_class_limits: array of length 'length_array' * 'n_classes' (modified) // values: sorted array of data values (unmodified) // n_classes: number of classes // length_array: length of the 'values' array static void JenksMatrices(double *variance_combinations, int *lower_class_limits, double *values, unsigned int n_classes, unsigned int length_array) { int lower_class_limit, i4; unsigned int i, j, l, m; double variance, val, sum, sum_squares, w, temp_val; // The width of the two matrices - this value is used in IX macro unsigned int width = n_classes; // Initialise the matrices with the expected value, as per fish.f code for (j = 0; j < n_classes; j++) { lower_class_limits[IX(0, j)] = 1; for (i = 0; i < length_array; i++) { variance_combinations[IX(i, j)] = DBL_MAX; } } variance = 0; for (l = 0; l < length_array; l++) { sum = sum_squares = w = 0.0; for (m = 0; m <= l; m++) { lower_class_limit = l - m; val = values[lower_class_limit]; w += 1.0; sum += val; sum_squares += val * val; variance = sum_squares - (sum * sum) / w; i4 = lower_class_limit - 1; if(i4 > -1) { for (j = 1; j < n_classes; j++) { temp_val = (variance + variance_combinations[IX(i4, j - 1)]); if (variance_combinations[IX(l, j)] >= temp_val) { // We still add '1' because fish.f code uses 1-based indexing // and we want to obtain the exact same result for later testing // (we take this into account when actually building the breaks array in Python code - // also note that changing this, ie not adding 1 here, would also require to initialise the // array at 0 and not 1, line 32 and 68 of this file): lower_class_limits[IX(l, j)] = lower_class_limit + 1; variance_combinations[IX(l, j)] = temp_val; } } } } lower_class_limits[IX(l, 0)] = 1; variance_combinations[IX(l, 0)] = variance; } } // Macro to access the elements of our matrices // using the same arithmetic than fish.f // (with fortran array that starts at 1) #define IXF(i,j) ((i)-1)*(width)+((j)-1) #define I(i) ((i)-1) // Compute FisherJenks matrices. // It use the same arithmetic as in fish.f, so we can verify that the results are the same // (this function is *not* used when calling 'jenks_breaks' but only when calling // 'jenks_matrices' with the arguments "testing_algo" set to True). // ---------------------------------------------------------------------------- // Parameters: // variance_combinations: array of length 'length_array' * 'n_classes' (modified) // lower_class_limits: array of length 'length_array' * 'n_classes' (modified) // values: sorted array of data values (unmodified) // n_classes: number of classes // length_array: length of the 'values' array static void JenksMatricesTest(double *variance_combinations, int *lower_class_limits, double *values, unsigned int n_classes, unsigned int length_array) { int lower_class_limit, i4; unsigned int i, j, l, m; double variance, val, sum, sum_squares, w; // The width of the two matrices - this value is used in IXF macro unsigned int width = n_classes; // Initialise the matrices with the expected value, as per fish.f code for (j = 1; j <= n_classes; j++) { lower_class_limits[IXF(1, j)] = 1; variance_combinations[IXF(1, j)] = 0.0; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // We do this to exactly mimic the original code (as this is our testing function) // but this is useless as we will overwrite the values in the following loop: for (i = 1; i <= length_array; i++) { variance_combinations[IXF(i, j)] = DBL_MAX; } } variance = 0; for (l = 1; l <= length_array; l++) { sum = sum_squares = w = 0.0; for (m = 1; m <= l; m++) { lower_class_limit = l - m + 1; val = values[I(lower_class_limit)]; w = (double) m; sum += val; sum_squares += val * val; variance = sum_squares - (sum * sum) / w; i4 = lower_class_limit - 1; if(i4 != 0) { for (j = 2; j <= n_classes; j++) { if (variance_combinations[IXF(l, j)] >= (variance + variance_combinations[IXF(i4, j - 1)])) { lower_class_limits[IXF(l, j)] = lower_class_limit; variance_combinations[IXF(l, j)] = (variance + variance_combinations[IXF(i4, j - 1)]); } } } } lower_class_limits[IXF(l, 1)] = 1; variance_combinations[IXF(l, 1)] = variance; } } ================================================ FILE: jenkspy/src/jenks.pyx ================================================ # -*- coding: utf-8 -*- # cython: language_level=3 from libc.stdlib cimport malloc, free import numpy as np cdef extern from "_jenks.c": void *JenksMatrices(double *variance_combinations, int *lower_class_limits, double *values, unsigned int n_classes, unsigned int length_array) void *JenksMatricesTest(double *variance_combinations, int *lower_class_limits, double *values, unsigned int n_classes, unsigned int length_array) cpdef list _jenks_breaks(values, n_classes): cdef: list breaks = [] unsigned int _n_classes = int(n_classes) # How many classes (clusters) unsigned int _n_breaks = _n_classes + 1 # How many class boundaries unsigned int len_values = len(values) # How many values to classify unsigned int i int *_lower_class_limits = malloc((len_values * _n_classes) * sizeof(int)) double *_variance_combinations = malloc((len_values * _n_classes) * sizeof(double)) unsigned int m, k, jj # Indexes for fetching break values from _lower_class_limits matrix sorted_values = np.sort(values) # Sort the values to classify double[:] _sorted_values = sorted_values.astype(np.float64) # Convert to double array # Fill the lower_class_limits and variance_combinations matrices JenksMatrices(_variance_combinations, _lower_class_limits, &_sorted_values[0], _n_classes, len_values) # Fill the breaks array with minimum value of the target array for i in range(_n_breaks): breaks.append(sorted_values[0]) # Last break value is the maximum of the array breaks[_n_classes] = sorted_values[-1] # Read the class limits from the lower_class_limits matrix m = len_values for j in range(1, _n_classes): jj = _n_classes - j + 1 # Note that the indexes contained in the _lower_class_limits matrix are 1-based, # so we have to subtract 1 to get the correct index breaks[jj - 1] = sorted_values[_lower_class_limits[(m - 1) * _n_classes + (jj - 1)] - 2] m = _lower_class_limits[(m - 1) * _n_classes + (jj - 1)] - 1 # Free memory we manually allocated free(_lower_class_limits) free(_variance_combinations) return breaks cpdef dict _jenks_matrices(values, n_classes, testing_algo=False): cdef: unsigned int _n_classes = int(n_classes) # How many classes (clusters) unsigned int len_values = len(values) # How many values to classify unsigned int i int *_lower_class_limits = malloc((len_values * _n_classes) * sizeof(int)) double *_variance_combinations = malloc((len_values * _n_classes) * sizeof(double)) unsigned int m, k, jj # Indexes for fetching break values from _lower_class_limits matrix list lower_class_limits = [] list variance_combinations = [] sorted_values = np.sort(values) # Sort the values to classify double[:] _sorted_values = sorted_values.astype(np.float64) # Convert to double array # Fill the lower_class_limits and variance_combinations matrices if not testing_algo: JenksMatrices(_variance_combinations, _lower_class_limits, &_sorted_values[0], _n_classes, len_values) else: JenksMatricesTest(_variance_combinations, _lower_class_limits, &_sorted_values[0], _n_classes, len_values) # Reconstruct the lower class limits matrix and the variance combinations matrix # from the 1D arrays that we use in C code for i in range(len_values): lower_class_limits.append([]) variance_combinations.append([]) for j in range(_n_classes): lower_class_limits[i].append(_lower_class_limits[i * _n_classes + j]) variance_combinations[i].append(_variance_combinations[i * _n_classes + j]) # Free memory we manually allocated free(_lower_class_limits) free(_variance_combinations) return { "lower_class_limits": np.array(lower_class_limits), "variance_combinations": np.array(variance_combinations), } ================================================ FILE: pyproject.toml ================================================ [build-system] requires = ["setuptools >= 61.0", "Cython"] build-backend = "setuptools.build_meta" [project] name = 'jenkspy' dynamic = ["version"] dependencies = [ "numpy" ] requires-python = ">= 3.7" authors = [ {name = "Matthieu Viry", email = "matthieu.viry@cnrs.fr"}, ] maintainers = [ {name = "Matthieu Viry", email = "matthieu.viry@cnrs.fr"}, ] description = "Compute Natural Breaks (Fisher-Jenks algorithm)" readme = "README.md" license = {file = "LICENSE"} classifiers = [ "Programming Language :: Python", "Development Status :: 5 - Production/Stable", "Operating System :: OS Independent", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering", "Typing :: Typed", ] [project.urls] Homepage = "https://github.com/mthh/jenkspy" Repository = "https://github.com/mthh/jenkspy.git" Issues = "https://github.com/mthh/jenkspy/issues" Changelog = "https://github.com/mthh/jenkspy/blob/master/CHANGES.rst" [tool.setuptools] packages = ["jenkspy"] include-package-data = false [tool.setuptools.package-data] jenkspy = ["src/*"] [tool.setuptools.dynamic] version = {attr = "jenkspy.__version__"} readme = {file = "README.md", content-type = "text/x-rst"} ================================================ FILE: setup.py ================================================ # -*- coding: utf-8 -*- from setuptools import setup from setuptools import Extension from Cython.Build import cythonize from Cython.Distutils import build_ext exts = [ Extension( "jenkspy.jenks", ["jenkspy/src/jenks.pyx"], ["jenkspy"], ) ] setup( ext_modules=cythonize(exts), cmdclass={'build_ext': build_ext} ) ================================================ FILE: tests/__init__.py ================================================ ================================================ FILE: tests/test.json ================================================ [5.005121249705553,6.7698845686391,1.021586733404547,9.385886443778872,4.548310353420675,6.354603075888008,8.976253494620323,5.191713236272335,4.7715608100406826,7.863712448161095,6.641501183621585,6.910042501986027,3.1715067266486585,0.873259964864701,4.488653743173927,8.203441253863275,9.454990027006716,4.74380933213979,2.5307508395053446,1.0617040214128792,5.692806332372129,9.596363012678921,8.741002352908254,7.56973524345085,9.692003140226007,4.701106182765216,0.25467247469350696,4.183835571166128,8.283707208465785,0.4071679199114442,0.8745960821397603,1.1438903491944075,8.09175917180255,7.531579013448209,3.8455851934850216,6.937670034822077,9.154734222684056,8.531235912814736,0.5893597682006657,2.1916877175681293,8.572350428439677,5.654468149878085,4.872281996067613,7.774307862855494,3.458382107783109,0.21459681214764714,5.651148806791753,8.170698226895183,3.793332518544048,3.538043680600822,5.262194804381579,4.906901775393635,7.565307286567986,0.5521937622688711,3.6833292455412447,3.1848908960819244,3.247706927359104,4.195517904590815,2.6592070376500487,4.42317585228011,9.517835441511124,3.8378226244822145,4.352589515037835,2.377250143326819,3.605512287467718,3.783397921361029,8.00054794875905,6.7187818652018905,9.887720327824354,8.047464538831264,1.3808186585083604,1.1643479787744582,3.2511105993762612,7.0645455829799175,6.015346504282206,3.0592047097161412,0.11540454113855958,8.06422257097438,8.150190676096827,7.356889457441866,7.555075858253986,8.846610595937818,2.7350123319774866,2.8688491880893707,5.752881758380681,4.483968471176922,3.128918393049389,1.8225139006972313,7.320002722553909,7.310214806348085,3.1840061768889427,7.529367180541158,3.4418908250518143,0.6517991703003645,6.738502050284296,8.91559086740017,6.276790397241712,2.616307910066098,6.629365314729512,5.17618608660996,9.019755569752306,8.813637949060649,1.5809390135109425,8.608846133574843,6.297092293389142,3.366280284244567,3.6157000600360334,7.385678398422897,3.0267058545723557,4.512188772205263,8.192399628460407,9.405485524330288,9.259929498657584,7.286311434581876,3.183465248439461,4.278770429082215,5.716953268274665,0.5789715587161481,3.8978533656336367,2.7586988173425198,5.059975730255246,2.3651492060162127,7.258396679535508,8.921859709080309,0.7392698503099382,5.230259886011481,7.899435206782073,4.09611314535141,4.389314744621515,1.6261946968734264,5.482187354937196,3.619761881418526,6.7433681595139205,5.937277122866362,7.241670216899365,3.9092640252783895,3.0374779948033392,4.2955951928161085,6.564467148855329,3.4312051092274487,7.994420470204204,8.576327294576913,9.310934916138649,4.1444108029827476,4.47236706269905,4.259377422276884,2.6667816913686693,2.4589728680439293,7.630906035192311,0.9030878497287631,0.8322572009637952,4.516582794021815,6.804379390086979,6.603685477748513,8.616967084817588,9.897620112169534,3.538529332727194,6.723157810047269,9.502576938830316,1.928999195806682,1.8021492660045624,0.3319901507347822,2.830298824701458,1.7497945064678788,8.641119801905006,6.753190960735083,5.087939640507102,0.24097285699099302,7.77379872975871,0.07630433887243271,5.831179551314563,1.980308259371668,9.021186453755945,6.7430946649983525,1.1699359631165862,4.425695182289928,4.411204196512699,0.436347268987447,0.016210493631660938,5.219610997010022,1.8238594755530357,4.391072562430054,1.6635660687461495,2.327323257923126,3.8895407621748745,0.34937486285343766,4.997782437130809,1.470987843349576,5.134017190430313,8.724819300696254,8.439850499853492,9.617690306622535,8.46617536386475,5.261317393742502,5.368968558032066,0.63983608270064,2.8225722163915634,8.938500019721687,7.147181977052242,8.128877335693687,9.535556964110583,3.1864461838267744,6.488277849275619,9.002741042058915,9.926652549766004,2.017675314564258,1.8869244935922325,7.829469197895378,9.87749854568392,8.060033479705453,7.224856070242822,1.2798929936252534,2.78866914100945,2.915852377191186,8.727970635518432,0.10094035184010863,1.2769153341650963,9.917198012117296,3.9630167349241674,4.305270852055401,0.39072010898962617,1.4237130340188742,7.404117160476744,2.124632552731782,5.738911542575806,8.455500639975071,0.3971548075787723,0.38380363257601857,7.651389359962195,1.1605408694595098,9.019916146062315,8.391325266566128,0.2516297739930451,3.871866795234382,9.364075737539679,8.019426786340773,1.9251802214421332,1.6824836819432676,4.3521748832426965,6.440906967036426,5.670455403160304,9.13355672499165,9.674578139092773,3.551772041246295,4.358341677580029,0.5826962715946138,4.618741385638714,3.46079527400434,6.279087632428855,5.707049502525479,1.2955440115183592,3.9778111944906414,6.086649831850082,3.367316094227135,7.954099648632109,9.675174430012703,2.9813746945001185,6.1050392431207,9.072706694714725,1.0152084473520517,5.0129653653129935,4.4952176278457046,4.828229963313788,2.80279049417004,9.726273817941546,8.393716011196375,2.9691689158789814,0.5977230123244226,3.2966522267088294,1.9834079663269222,2.443813297431916,9.3139135860838,9.593252062331885,9.561771580483764,4.565526058431715,3.565698068123311,2.93719359440729,0.23579740431159735,8.647503587417305,5.528719199355692,3.2021239260211587,1.8626428116112947,7.162086877506226,8.009240166284144,2.8634931123815477,1.7266137595288455,1.3530070381239057,6.1247731652110815,0.39224540116265416,5.389998119790107,7.785557424649596,2.0238707633689046,4.911097213625908,9.156511554028839,7.698650665115565,5.17227322794497,1.703380816616118,0.2752389758825302,8.36603713221848,4.027513647451997,0.5095890816301107,2.6868695090524852,0.8549958374351263,8.37044699350372,0.1689472864381969,9.155438302550465,1.979340200778097,3.9153014589101076,8.676073581445962,7.258209879510105,5.105281511787325,0.33225199673324823,1.6601247829385102,0.5513627780601382,1.5807324997149408,7.9406681773252785,1.7205733619630337,9.603691045194864,2.8630179027095437,4.047275122720748,9.35481598135084,5.894196014851332,8.898273101076484,1.2117962702177465,3.427451769821346,1.6751115024089813,7.450441187247634,6.333751284983009,9.191068122163415,4.751952183432877,6.507860643323511,3.5455762362107635,6.3690619939006865,3.579293512739241,0.19884062465280294,9.890686634462327,9.903192091733217,1.2413786933757365,5.322804823517799,8.168133283033967,7.936764496844262,5.9427399933338165,0.9801914123818278,5.634015267714858,6.3429148006252944,1.7967454460449517,2.8216620441526175,9.046308181714267,7.734155275393277,6.892145269084722,0.04080339800566435,2.1992984949611127,1.3171452400274575,0.32386996783316135,8.644907760899514,4.66755909146741,3.7622552318498492,2.125490119215101,2.8469666210003197,8.956255142111331,1.2864466197788715,5.9537597838789225,7.54667735658586,9.981639247853309,6.530319538433105,1.8452655454166234,2.3217288847081363,2.8669062978588045,7.299607910681516,3.280770897399634,8.299202625639737,5.9492160845547915,4.460666803643107,3.553754521999508,5.6664344016462564,9.560894852038473,5.347238974645734,0.3324538213200867,5.212724609300494,4.806412188336253,5.222975553479046,1.4713243208825588,2.8643993102014065,8.965555771719664,9.282951881177723,1.2171179172582924,4.608287604060024,0.5520726274698973,8.675954404752702,7.713990451302379,0.13574847718700767,3.2274405867792666,8.782945298589766,6.04509849101305,8.638825516682118,4.733543619513512,4.097544157411903,3.721517384983599,4.021191922947764,6.29044895991683,8.46637294627726,4.789086079690605,8.02990790689364,7.917316320817918,1.7982503399252892,9.051917910110205,9.219823577441275,8.304803299251944,6.587984832003713,0.4525634692981839,9.205476662609726,8.69195195613429,3.133157326374203,7.33994496287778,4.329452724196017,1.176558828447014,6.435436676256359,9.529366253409535,5.608214184176177,5.422785482369363,4.287649565376341,8.058759570121765,8.239792054519057,4.051151594612747,8.468851919751614,6.68550766305998,4.970433753915131,2.0520593179389834,9.25285060191527,9.765314108226448,9.101411416195333,2.4982762103900313,2.5175985251553357,1.5851920936256647,3.5294777341187,1.9903180748224258,7.282198499888182,1.450364924967289,1.4495945163071156,4.4885895238257945,6.970178484916687,3.228607119526714,9.508843086659908,5.969138853251934,9.360267603769898,8.201031668577343,5.504413950257003,0.444363160058856,8.794365208595991,6.478337696753442,3.0571653158403933,4.69496059929952,8.5105563653633,5.721606253646314,3.770676008425653,7.1668785670772195,4.977014765609056,5.109445441048592,9.161017963197082,2.3393165739253163,4.160092850215733,5.534558251965791,5.571234594099224,5.829149051569402,3.7799159716814756,4.490721246693283,2.9286981048062444,7.837946303188801,9.09732264932245,5.284380256198347,6.569127740804106,0.14224236132577062,0.7112566940486431,3.2313932687975466,8.649088197853416,6.337066187988967,0.8665623585693538,0.5975108221173286,9.225046874489635,7.021017279475927,3.03283863235265,0.8192361425608397,1.8364296993240714,6.679474604316056,9.500770999584347,5.6698150699958205,0.469330467749387,0.5351261119358242,2.210079834330827,8.722575556021184,6.498342743143439,1.0846159583888948,3.6406051204539835,2.385515032801777,6.760069322772324,5.329264551401138,8.447717593517154,5.750391592737287,4.457062541041523,2.397960973903537,1.4404313871636987,0.9434649487957358,3.8073990773409605,0.8290260541252792,6.076578572392464,2.889620845671743,1.7025700793601573,7.7888068510219455,5.125095532275736,2.25424395641312,2.3183451360091567,3.9721389510668814,0.41902625001966953,9.24581942614168,8.262916828971356,3.315193944144994,5.921145835891366,0.035002054646611214,7.369782589375973,4.383812777232379,5.889177967328578,9.923857869580388,2.355423846747726,2.95550178270787,3.789925987366587,8.410550525877625,9.414464952424169,8.00936208339408,0.7033347873948514,1.8303936417214572,5.814342319499701,9.248531309422106,4.3787982617504895,0.6746661965735257,1.053044784348458,8.336823675781488,0.29698571190238,9.174948441796005,5.18295472022146,1.4739059610292315,0.9499002108350396,6.4988583931699395,5.646643748041242,4.88169884076342,8.310269580688328,3.4229141660034657,4.430989425163716,9.839584520086646,4.932196433655918,9.598212733399123,4.078633387107402,2.124364417977631,6.205928954295814,1.1621719202958047,2.075500339269638,5.247691301628947,9.616502453573048,0.8466748869977891,1.3727407669648528,3.2300059543922544,3.7397971469908953,6.974140224047005,7.605024427175522,8.858814416453242,3.0201582750305533,8.513688761740923,6.1404573218896985,9.818810618016869,4.814249349292368,3.586849682033062,5.691904278937727,0.08578629698604345,8.12171152094379,0.2463038545101881,0.631671582814306,6.405444687698036,1.247334333602339,5.87713137967512,7.142814432736486,4.084130122791976,5.3019098727963865,0.6986237247474492,5.578774176537991,6.922094707842916,3.1462549371644855,5.241006824653596,7.232290639076382,0.6026483443565667,1.3768058666028082,0.08003556169569492,3.056485091801733,0.36391520174220204,9.648529915139079,0.8321366808377206,4.8639202932827175,0.04729584092274308,4.557534940540791,8.954018091317266,2.728234075475484,3.9430438703857362,8.676431993953884,7.024349491111934,7.706452382262796,7.474976892117411,9.013208753895015,3.983901480678469,3.2532308739610016,3.856631957460195,0.6799420155584812,4.071933226659894,3.9262308925390244,3.7392733758315444,1.5917768306098878,0.279220484662801,1.5261770808137953,6.645503242034465,7.39584710681811,5.803650752641261,4.92629227694124,3.2169264694675803,4.9417629931122065,6.19889791123569,1.5975867537781596,8.312263281550258,0.14834391651675105,2.029930637218058,6.402105689048767,6.113263389561325,1.985282285604626,2.505738395266235,8.142135050147772,8.030197187326849,0.9432496968656778,3.553340518847108,1.2001235736534,7.0014568767510355,0.8712048991583288,7.218146389350295,3.108048194553703,0.5959121184423566,8.937904289923608,4.43502742331475,5.265623216982931,9.983510402962565,7.959266698453575,6.320372137706727,6.3003423204645514,5.463160099461675,3.3636903017759323,8.07415701681748,6.806202935986221,8.266241094097495,5.370127386413515,6.115587130188942,3.5212122928351164,3.627032130025327,9.335073630791157,0.2766379411332309,3.4970815549604595,6.336682494729757,1.0654873517341912,2.2779573663137853,7.545566235203296,5.954197410028428,5.806731297634542,4.015602404251695,9.525050513911992,4.77150441147387,2.7979273931123316,3.2749838870950043,9.45563584798947,0.09879812132567167,2.4449413153342903,5.518020107410848,6.296010280493647,1.592619251459837,6.327643119730055,3.2402966916561127,7.0537514868192375,1.5324516058899462,5.881986066233367,6.6874419478699565,7.011232525110245,5.271969200111926,6.413867732044309,8.923816692549735,9.083089362829924,7.67493249848485,8.792618461884558,1.5498139732517302,4.922635336406529,6.5072737680748105,5.22849471308291,5.351687946822494,2.0744572672992945,7.13923693401739,5.409126812592149,0.9846348548308015,9.132452446501702,9.788705580867827,7.06255468307063,4.379081064835191,1.459092313889414,8.872436513192952,7.824255577288568,1.9047077163122594,5.91305744368583,3.95631808321923,8.415001172106713,6.593160284683108,9.465731894597411,1.5623756009154022,7.231087188702077,7.968563807662576,4.240919598378241,9.750124081037939,9.57732462324202,5.524232855532318,8.876056729350239,5.419644471257925,3.8573184912092984,8.71060271281749,7.383526682388037,2.6232833857648075,2.167216648813337,0.6891097198240459,1.5929507254622877,7.552667181007564,6.112799821421504,3.2445063162595034,5.761312402319163,1.4269530004821718,6.757629525382072,9.055622359737754,4.490635963156819,3.005405543372035,3.1100730877369642,3.336475242394954,9.020458811428398,6.665812183637172,0.5622236523777246,0.24418123299255967,6.458999204915017,9.113601909484714,5.332121967803687,9.051467652898282,2.5377386272884905,0.06617928855121136,8.953536252956837,9.625905477441847,9.871210381388664,0.06093396572396159,5.500918184407055,6.136398678645492,3.455249024555087,7.022403746377677,4.186076687183231,9.447183585725725,0.7258855388499796,4.193982670549303,4.073762791231275,3.48527958849445,7.124344191979617,7.4344271956942976,2.058891821652651,6.108035012148321,9.700778108090162,7.40551418159157,4.405704005621374,1.5880355378612876,8.668289298657328,0.9236494894139469,0.5630778265185654,4.675268935970962,7.89153668563813,8.95357889123261,1.1104525881819427,1.114057411905378,5.148262919392437,2.8109398880042136,8.986127427779138,4.742131666280329,1.729847362730652,2.5206953077577055,4.106387132778764,9.701968322042376,7.759640198200941,5.740222258027643,0.24120857240632176,1.4410786493681371,8.009897889569402,8.936529501806945,0.9522559540346265,3.43249773606658,6.40288537601009,3.234312899876386,8.333164108917117,3.9870322681963444,0.91971087269485,5.128620658069849,2.376817553304136,1.0331127932295203,8.431752701289952,3.8787931436672807,7.11586213670671,5.129346714820713,9.439627323299646,2.730485238134861,3.1133452500216663,7.389392589684576,2.136833011172712,6.702913187909871,9.67047925805673,1.3177918968722224,8.438838790170848,5.005237511359155,0.18251155503094196,4.0377202443778515,6.433610245585442,3.1418353994376957,0.7609018008224666,3.2746874215081334,9.826047737151384,2.9710332467220724,7.243791192304343,8.390633163508028,4.1798886633478105,3.875475013628602,6.680055041797459,5.404357824008912,7.209625213872641,0.32174521358683705,0.5552434921264648,4.398770937696099,9.327740897424519,1.0799965169280767,0.782781180460006,6.297578073572367,0.9427543310448527,5.402197553776205,9.3627410242334,4.048871209379286,8.352442337200046,0.6531258439645171,8.322408152744174,0.4232423333451152,8.529539406299591,8.878272820729762,9.475544735323638,9.252802892588079,3.4703456796705723,7.412700990680605,6.745369881391525,8.362561122048646,9.61106286616996,9.246906617190689,1.7375518730841577,5.280082421377301,2.023140504024923,0.27117491932585835,8.990772373508662,2.1041698241606355,8.830703268758953,5.421146000735462,8.241722732782364,3.047999022528529,8.589261856395751,9.114171438850462,2.89663860341534,7.77944823494181,8.405141171533614,2.2412185254506767,1.1118765827268362,0.15475268010050058,9.219623620156199,2.3388031870126724,6.74962900346145,7.11000258103013,8.58264237176627,9.65570705709979,2.777035520412028,9.163185663055629,2.1187206404283643,7.487841993570328,0.7285763695836067,3.8358826097100973,4.958077329210937,3.3186359121464193,7.494144381489605,9.805061717052013,1.4622714277356863,1.2707394803874195,7.372791413217783,6.766709061339498,5.220039028208703,2.0707297744229436,7.155217160470784,9.567439665552229,2.1715411194600165,3.0287244147621095,2.0935479691252112,5.7181795057840645,1.3374383770860732,1.4437670982442796,2.229987601749599,5.629292957019061,4.438080200925469,2.8963091038167477,3.2311262539587915,9.258770167361945,7.682583821006119,0.3442920558154583,7.52879191422835,4.285130866337568,3.3373237471096218,3.9863606193102896,2.7974618948064744,0.5093348119407892,8.161671336274594,3.6710569192655385,0.15639419667422771,4.785774836782366,4.371580411680043,5.59470092644915,4.196186689659953,3.5285426396876574,7.624466461129487,7.821976104751229,7.641605953685939,4.090073329862207,9.302951826248318,7.207879973575473,4.920398378744721,9.290684608276933,5.774778400082141,0.8102608169429004,6.003749766387045,9.865081324242055,9.61276046000421,7.548458769451827,0.2787048486061394,3.6695049051195383,7.046924394089729,4.78735726326704,0.690148170106113,1.3847953011281788,1.3659868156537414,5.81805907888338,6.036841187160462,7.247420330531895,0.5867991875857115,7.918846395332366,4.816894670948386,9.760163868777454,3.761894265189767,9.604116266127676,3.8879027497023344,2.645444783847779,6.8812884646467865,3.4451603051275015,9.480039989575744,6.96180027211085,9.176043886691332,3.7707790383137763,7.432482750155032,7.664772956632078,7.793930487241596,2.525892131961882,8.50616543320939,0.7726947125047445,7.132422402501106,0.2727644005790353,6.206431726459414,9.707880192436278,4.99498043442145,7.618717472068965,1.5810609725303948,9.91091194562614,8.336031804792583,3.2491677603684366,0.02873112913221121,7.427574023604393,8.33627390442416,1.8594216601923108,1.4347189757972956,6.475316963624209,6.393060914706439,2.149796923622489,0.39602426113560796,9.804883578326553,5.756679147016257,7.7590328035876155,6.275271084159613,0.6845211144536734,6.302854046225548,8.503771356772631,0.6995680904947221,4.595206868834794,5.739592604804784,8.902673011180013,0.3918302967213094,7.799455195199698,0.6336134648881853,0.5764604662545025,0.6564780650660396,4.466231181286275,0.36326027708128095,0.979608295019716,5.016129771247506,3.0382750369608402,2.7278555394150317,9.505183058790863,4.730000076815486,8.81509207887575,9.661492721643299,2.2802249807864428,3.856866725254804,2.2590105165727437,1.1880779056809843,6.36979965493083,6.863516794983298,5.471703454386443,2.6916230213828385,4.49135904898867,7.960270547773689,9.18560468358919,0.405365030746907,3.940486554056406,8.994000100065023,0.286626061424613,9.060897070448846,8.880923427641392,5.6295722420327365,5.595777346752584,7.790995810646564,6.640329139772803,3.8866658601909876,4.392917102668434,0.81801469437778,4.092508296016604,1.3150955270975828,3.2104334188625216,3.343771027866751,0.7922920188866556,7.467067881952971,2.7943023410625756,7.35004672780633,8.955614177975804,0.6924187857657671,2.9766863374970853,2.982900079805404,5.149163547903299,0.7587808021344244,5.495809055864811,9.895763201639056,1.9980297749862075,5.680950589012355,0.2833250258117914,5.160863287746906,3.3061955450102687,6.126706663053483,5.092719225212932,3.471996681764722,0.40845570154488087,8.809545852709562,0.41240135207772255,0.7007679459638894,4.644989185035229,5.402957273181528,3.1835155142471194,8.874168668407947,2.0051661506295204,3.6553915264084935,3.342277437914163,0.7016782579012215,0.5557832703925669,2.1724525978788733,0.7305986527353525,5.11548722628504,5.323966674041003,5.280183479189873,9.296258958056569,1.8281864933669567,1.5077325911261141,0.6386737897992134,9.896054649725556,3.431777728255838,5.652669246774167,0.6770251714624465,2.5347269605845213,9.633591913152486,5.160807867068797,5.913102389313281,2.7730581490322948,7.716303537599742,1.0102198226377368,7.50285963062197,1.408177672419697,1.2599345133639872,1.4842764963395894,7.365092723630369,6.716901049949229,1.1312897270545363,8.296968115027994,9.103325819596648,8.576687227468938,4.2583829700015485,2.8992986981756985,4.522206841502339,0.5454922490753233,4.334308826364577,6.173307211138308,8.580648149363697,1.752965326886624,1.5858782338909805,0.2874048752710223,5.118917291983962,9.330119474325329,2.407601298764348,5.6703683151863515,1.7356508830562234,0.12674539349973202,1.2370011419989169,5.223798463121057,8.840755166020244,8.223172936122864,1.0479398723691702,9.127157032489777,5.0065735867246985,0.5894318339414895,2.6026442064903677,1.0727001912891865,3.677814626134932,0.6211163615807891,7.065325311850756,4.799406565725803,3.754234549123794,2.2943412489257753,0.1220970693975687,4.260414750315249,8.183126414660364,9.949804465286434,5.601314960513264,4.251789464615285,5.660751860123128,0.7730075158178806,4.006620328873396,7.100624938029796,9.826707723550498,7.9794110474176705,2.929651269223541,5.5398171790875494,2.1196571947075427,7.389518632553518,3.0125506641343236,7.995314311701804,0.309637226164341,9.109576425980777,4.850033402908593,5.836737265344709,8.567279109265655,6.991376981604844,4.719556211493909,9.211067028809339,5.137387553695589,9.19474045978859,6.912961232010275,5.466075958684087,4.419572269544005,6.171108540147543,9.810278152581304,0.772656574845314,3.3136177016422153,2.920890736859292,9.491652071010321,2.2066241479478776,0.5756494379602373,7.154275856446475,8.238706982228905,3.5841460758820176,5.064190095290542,2.0595223363488913,2.176204938441515,5.735069885849953,0.854919170960784,7.826219175476581,6.613375940360129,1.7721033305861056,1.6580536519177258,3.311698012985289,9.709230295848101,2.0702647999860346,7.25381653290242,4.254569071345031,7.006728227715939,9.31152175879106,3.466042666696012,3.0842236266471446,5.737497343216091,5.720236881170422,0.9332084935158491,1.9149792077951133,4.2891683196648955,7.054053777828813,3.67476599290967,3.7359976512379944,2.27169266436249,3.972181221470237,9.467683425173163,0.5641223234124482,3.7870318675413728,6.858365037478507,1.3455796614289284,1.6292286152020097,4.82172760181129,7.927085501141846,0.048026570584625006,7.261468344368041,8.920171388890594,6.584138963371515,5.797392474487424,5.503258719108999,5.377397791016847,9.180650466587394,7.6735916174948215,2.3314723069779575,5.271672031376511,4.652883606031537,7.2418782860040665,4.006839310750365,8.904543151147664,5.700144928414375,7.253411856945604,5.508117189165205,4.310129103250802,7.256692026276141,9.490583406295627,3.8978980178944767,0.8199827093631029,2.2928559873253107,8.633115680422634,4.007787087466568,2.536181048490107,9.142198492772877,7.274342041928321,7.062257567886263,4.6163533721119165,5.775722260586917,1.8128746724687517,6.125398916192353,0.9765034425072372,8.069729937706143,0.1609800406731665,6.871428689919412,0.12279951944947243,1.5686771203763783,9.641415146179497,1.5150466677732766,3.623195600230247,3.252211317885667,2.843856813851744,2.111335073132068,6.072979089803994,5.391069953329861,0.28139691799879074,3.9535815501585603,3.1713187973946333,8.895994999911636,6.296534081920981,2.293499584775418,2.010152053553611,7.317216149531305,2.750641289167106,0.3282890049740672,1.297422694042325,7.787100598216057,5.976826881524175,6.2007618509233,8.133389616850764,7.342623786535114,0.3353470587171614,0.1401476445607841,0.6348051363602281,5.62640700256452,6.834628670476377,8.287429567426443,8.760479835327715,2.464153717737645,9.948190136346966,7.518533570691943,2.483075982891023,9.525565390940756,8.28531475737691,7.446576666552573,6.379745360463858,8.449977647978812,9.502119636163116,9.166164598427713,1.84962299419567,2.5214252551086247,9.474943114910275,7.480313575360924,9.18577824253589,9.574639580678195,3.0873931501992047,3.902828844729811,8.955786465667188,1.822055319789797,1.2770397728309035,9.003044599667192,8.232472618110478,4.205495140049607,6.678732584696263,9.705365237314254,3.303111109416932,1.6291389521211386,4.670131162274629,4.783018177840859,7.774069514125586,6.918880138546228,0.0847647269256413,7.310405981261283,6.046568390447646,4.71660397015512,8.759698749054223,9.162689112126827,4.724578890018165,8.798923729918897,3.4097588481381536,9.658417680766433,0.8257632004097104,9.154552412219346,1.7069766810163856,2.0297640305943787,0.32220604130998254,8.870249604806304,0.8042637398466468,1.6107536456547678,2.870572868268937,1.927663697861135,1.8293870287016034,6.638193135149777,0.15985927311703563,3.469282186124474,4.662023081909865,6.822183250915259,0.07973068626597524,5.27177037904039,9.602021172177047,0.3938668267801404,4.24152075080201,9.488032115623355,3.5663137235678732,6.400670511648059,8.659203653223813,1.9419052777811885,6.476652035489678,2.5672774179838598,8.872400331310928,6.980321214068681,0.5659185512922704,5.1587631017901,0.16739953309297562,0.3771748370490968,9.78439987404272,4.459752687253058,3.7111810967326164,2.431070290040225,7.674493484664708,5.543658756650984,6.178148351609707,1.1710951244458556,8.90641275094822,3.944787213113159,3.161431953776628,6.2640175595879555,3.0730902426876128,6.702820162754506,4.11391464760527,1.9151894887909293,9.35838958248496,2.217791029252112,7.806389082688838,5.219341707415879,9.116828937549144,7.963402427267283,8.572508585639298,3.778735229279846,7.3732008738443255,3.7390939285978675,0.4619262972846627,1.9791384623385966,8.00595281412825,3.56250875396654,3.9490386354736984,4.621090982109308,7.616894841194153,9.411722305230796,8.994079555850476,1.8118510814383626,4.475696457084268,6.3445988786406815,9.355857539921999,9.537861722055823,2.563942053820938,0.4753952892497182,6.078333002515137,4.1584666282869875,2.1797239361330867,0.4499889397993684,7.546788947656751,3.326692469418049,0.4163886094465852,8.180438366252929,2.8719682176597416,8.853986996691674,1.7794578382745385,3.3300268999300897,2.240218697115779,4.361645104363561,8.770431957673281,4.937058859504759,1.312054772861302,6.286779607180506,1.4903844916261733,6.811417683493346,0.5334125878289342,3.3075830689631402,3.416214669123292,3.838753046002239,0.7749398867599666,9.048466596286744,5.261005235370249,2.0465035107918084,8.26013441896066,9.483851396944374,7.31332222931087,1.1874781618826091,6.626302050426602,9.710194584913552,6.238884350750595,8.566150898113847,6.191658522002399,0.16678494168445468,2.9975258465856314,0.40159796364605427,9.024084887932986,2.067894882056862,1.7542802216485143,9.287410946562886,7.035958676133305,8.388541280291975,5.0866307923570275,9.088220556732267,3.737106502521783,6.08713440829888,4.694471629336476,8.658810071647167,4.736885798629373,5.443868017755449,0.21531900856643915,4.328751866705716,8.734100982546806,9.691879767924547,0.6026311591267586,5.0918229622766376,2.414504252374172,0.6562796025536954,8.007745193317533,4.561325695831329,6.4563240320421755,1.0674994997680187,3.437700199428946,7.750045235734433,4.608365250751376,6.1000909633003175,2.6345350174233317,8.13884753268212,3.695160890929401,9.056671024300158,9.669701177626848,6.6390090505592525,4.195509182754904,9.878272323403507,5.170153737999499,8.852205644361675,4.537872176151723,7.302804717328399,2.996683830861002,0.0850060279481113,0.39945898577570915,1.2676188396289945,9.220832276623696,7.742931165266782,5.870538945309818,9.997982932254672,3.707713894546032,0.5426692753098905,5.312947144266218,6.040325423236936,8.903734616469592,3.7200537347234786,8.87317496817559,8.910572861786932,1.374665042385459,5.452206975314766,4.963398557156324,3.448840258643031,5.863132041413337,6.359814011957496,7.869354677386582,9.31053961161524,0.4624076629988849,0.50285620149225,7.374885943718255,3.4966174489818513,6.466078041121364,0.6122018559835851,9.153956223744899,2.585089879576117,3.510377111379057,6.071923410054296,0.6867449101991951,7.3726611328311265,6.147802732884884,9.609369693789631,2.1416593273170292,4.45459084585309,6.082902064081281,0.30924258986487985,5.090798798482865,7.6942396513186395,3.8768380135297775,2.0571266440674663,3.0510861054062843,6.114556828979403,6.145044157747179,9.76746681611985,1.452829330228269,1.8749052751809359,6.703981806058437,8.41798685491085,7.54781034309417,5.306985436473042,7.160931697580963,5.725655315909535,5.888903685845435,4.721376013476402,5.848252370487899,9.98144534882158,1.8746388657018542,7.232015256304294,7.117245784029365,1.855696034617722,1.3886801432818174,9.305877354927361,2.219520155340433,6.130027202889323,5.434409484732896,9.368655756115913,0.010560411028563976,2.909986381419003,0.8472597342915833,5.535500969272107,6.497512315399945,3.22523461189121,8.036356137599796,1.1022535758093,1.9288622331805527,1.5512380236759782,0.8913211128674448,4.4428992457687855,5.222196257673204,6.0349663882516325,4.319484701845795,0.2740642870776355,7.4866299401037395,6.5149042825214565,1.8699029320850968,1.224007597193122,8.709125821478665,0.8581114909611642,7.208434175699949,0.2330804825760424,8.256173769477755,2.999106957577169,1.4772750926204026,3.076366998720914,8.800826682709157,5.014731714036316,8.033633518498391,9.080262936186045,3.056185571476817,5.205376564990729,1.0332584264688194,2.947180198971182,3.553388479631394,7.335517478641123,9.405087830964476,8.324133488349617,2.8369443770498037,4.569727415218949,0.0028109620325267315,4.491785375867039,4.181515297386795,8.579165309201926,9.589058754500002,5.710007438901812,0.7714147912338376,7.076025784481317,4.897682091686875,3.109375536441803,8.52890222799033,0.8067928743548691,3.339387560263276,2.7486888831481338,0.1834739069454372,0.13786843745037913,9.225133599247783,4.104528869502246,6.718224517535418,9.042769731022418,6.782753930892795,6.359363845549524,3.2467037439346313,6.956676165573299,1.002732792403549,7.878509892616421,6.505595904309303,3.9875898300670087,9.472178118303418,0.033289180137217045,2.1123246382921934,6.898302035406232,2.790963838342577,5.609240636695176,6.547042510937899,7.332089270930737,1.687012780457735,9.050792825873941,4.550500046461821,2.508453610353172,8.34862070158124,0.5174473067745566,2.365494992118329,7.8418893297202885,7.949061542749405,5.1846180856227875,4.135512995999306,6.027367771603167,8.786611303221434,7.2287139017134905,8.400008329190314,5.652564191259444,6.485898280516267,1.5929361968301237,3.3511886931955814,6.965320943854749,7.1733984421007335,6.4590505650267005,3.3780623809434474,2.53732934826985,7.090107607655227,4.937354400753975,0.1462509809061885,8.326996385585517,6.020387683529407,8.211010524537414,0.6880706432275474,6.092719400767237,7.7066361997276545,5.124120262917131,8.530900250189006,3.191711043473333,7.281458636280149,8.541571113746613,4.788106638006866,0.8656909805722535,9.950766898691654,3.775679904501885,6.872359309345484,6.466396288014948,5.735910239163786,6.930676903575659,0.028583097737282515,6.362798169720918,3.401729306206107,1.8991571152582765,9.183174695353955,8.527052854187787,3.920709218364209,3.9081501052714884,0.5026421789079905,8.57710946816951,3.2544350367970765,8.381201976444572,6.014232321176678,2.2734661516733468,3.884390089660883,7.168968559708446,3.1055986578576267,0.8504488063044846,0.6574258208274841,1.9687496963888407,1.2488291063345969,3.9164828951470554,3.5668431571684778,5.303401290439069,3.556828510481864,8.636603229679167,2.2163238376379013,8.328525421675295,7.96512397704646,2.508733293507248,4.877198901958764,1.696917014196515,5.875644078478217,1.0215720790438354,7.742140111513436,3.8253072323277593,3.827912879642099,5.0153932883404195,8.497627591714263,9.051827022340149,6.663935126271099,2.6890286710113287,4.635762011166662,2.8451002947986126,1.317774683702737,3.7477840180508792,7.005943777039647,6.863876138813794,8.196028764359653,2.796280402690172,2.1653333492577076,0.3082891320809722,5.177921887952834,9.081181653309613,5.503672880586237,3.022115209605545,8.704451217781752,8.409341319929808,5.449645619373769,8.13090322073549,4.612170911859721,4.974079809617251,8.63246324006468,3.6019188771024346,4.883304922841489,8.410894167609513,0.1754862884990871,6.9699426321312785,6.449795283842832,3.2386696618050337,6.872938610613346,9.560737845022231,8.015959477052093,4.820810530800372,5.76675301650539,5.969588891603053,9.71083827316761,6.270281868055463,6.4288035640493035,4.540399077814072,1.238783011212945,2.70120911533013,2.455858471803367,9.08755749464035,7.42733390070498,0.16459927195683122,7.792567100841552,5.340316668152809,8.550936542451382,3.6319944611750543,2.0526350010186434,8.638602651190013,2.9231304302811623,5.132332989014685,6.8238003039732575,2.972788519691676,4.986278247088194,8.902562253642827,9.726327853277326,2.4262788868509233,5.7048242329619825,0.4887069808319211,6.045272841583937,4.690704664681107,0.3353210841305554,8.006177013739944,8.680784935131669,2.0461021014489233,8.06122918613255,5.95336735015735,0.6149334507063031,3.381724094506353,9.917126761283726,7.5794518971815705,9.861289612017572,8.255028801504523,6.40686403028667,2.1936482144519687,4.350684678647667,2.186387076508254,4.124441018793732,5.135223595425487,8.044509517494589,8.714396869763732,1.286247547250241,2.401028040330857,3.2922549708746374,8.839298854582012,0.4996850760653615,0.7018996053375304,0.4600142454728484,3.947083200328052,2.629854765255004,5.5269017606042325,3.641773136332631,6.171250171028078,7.958270467352122,4.345328859053552,4.113983828574419,8.228186129126698,3.1365121947601438,0.8844565250910819,5.231514738406986,7.216556174680591,5.046960632316768,3.8190950616262853,0.15302482061088085,0.6978752231225371,4.3839905597269535,3.090344632510096,5.431912227068096,1.5771419298835099,0.29228524304926395,6.4315836620517075,0.27367391623556614,7.62010051170364,3.9641580637544394,3.18216466344893,1.7433763318695128,4.4212109060026705,5.803502427879721,7.126736051868647,2.236764603294432,9.896282262634486,3.6362336203455925,0.49861375242471695,0.4306951235048473,2.2750253067351878,0.9063962195068598,2.074180683121085,7.293821016792208,2.682933029718697,8.858296943362802,6.768294712528586,5.607374026440084,6.985351680777967,5.849818694405258,4.769126872997731,3.676380175165832,0.9810877963900566,5.216674394905567,3.2992141181603074,4.397831300739199,8.939810239244252,1.2864493671804667,1.070280079729855,7.304996794555336,5.247464687563479,4.800995299592614,2.5238397368229926,9.333614155184478,7.904198162723333,5.857936444226652,6.983835839200765,0.12860742630437016,4.067891526501626,5.004377830773592,7.81127599067986,7.552224041428417,8.087909475434572,9.61275911424309,6.355922950897366,1.997298183850944,2.147095089312643,7.587601693812758,0.3507608105428517,3.214240816887468,0.4481401271186769,8.558716361876577,4.226938223000616,3.3966982550919056,0.6860379711724818,0.5942504829727113,2.0161200338043272,0.008770730346441269,1.1269167135469615,1.1443942948244512,0.9506070939823985,2.6806247606873512,3.1751575088128448,7.550022893119603,0.5481684347614646,3.276002479251474,0.6785353692248464,9.754259421024472,9.442907175980508,8.390649778302759,7.125653347466141,4.137831430416554,9.08945154864341,5.778692571911961,3.945129052735865,1.3508908171206713,9.102336601354182,4.092890555039048,6.171590136364102,8.539728224277496,5.201710297260433,4.250538183841854,7.666936442255974,8.03294611396268,3.0906258476898074,3.6614765995182097,5.1746382471174,7.280544408131391,8.87948032002896,3.523988991510123,8.768577789887786,0.548009283374995,6.644843064714223,1.0905100358650088,5.908335722051561,3.8091140962205827,1.489883647300303,1.9381182617507875,5.468435357324779,4.856602211948484,1.9279759982600808,0.9892736119218171,0.41426529875025153,9.646270943339914,8.78195498837158,7.620176488999277,7.033941438421607,6.100081659387797,9.584738134872168,7.6452151709236205,8.710821862332523,3.31917988602072,5.510850565042347,3.8572997669689357,3.1595066795125604,9.054107670672238,6.999417408369482,9.843484414741397,8.839693872723728,4.4175667013041675,9.71137325745076,3.5052315215580165,1.8646901124157012,5.584472434129566,8.079652560409158,4.316841347608715,0.6563068926334381,4.355958045925945,7.952115361113101,1.612688945606351,0.6541568553075194,3.6283174948766828,3.6298038600943983,5.129724673461169,8.923856501933187,4.301771363243461,0.43236425379291177,6.794311958365142,8.65310367429629,1.4601672533899546,6.09687692951411,4.598260552156717,5.100484711583704,9.669725431594998,1.8093775934539735,8.658116031438112,8.355668031144887,1.1881286883726716,8.766729938797653,4.8027647053822875,7.902374111581594,4.165262170135975,6.765276649966836,1.3222630834206939,1.2765076151117682,6.316710694227368,2.3988837259821594,5.203518872149289,1.1172460136003792] ================================================ FILE: tests/test_jenks.py ================================================ # -*- coding: utf-8 -*- import unittest import numpy as np from array import array from jenkspy import JenksNaturalBreaks, jenks_breaks, _jenks_matrices test_data = [5.005121249705553,6.7698845686391,1.021586733404547,9.385886443778872,4.548310353420675,6.354603075888008,8.976253494620323,5.191713236272335,4.7715608100406826,7.863712448161095,6.641501183621585,6.910042501986027,3.1715067266486585,0.873259964864701,4.488653743173927,8.203441253863275,9.454990027006716,4.74380933213979,2.5307508395053446,1.0617040214128792,5.692806332372129,9.596363012678921,8.741002352908254,7.56973524345085,9.692003140226007,4.701106182765216,0.25467247469350696,4.183835571166128,8.283707208465785,0.4071679199114442,0.8745960821397603,1.1438903491944075,8.09175917180255,7.531579013448209,3.8455851934850216,6.937670034822077,9.154734222684056,8.531235912814736,0.5893597682006657,2.1916877175681293,8.572350428439677,5.654468149878085,4.872281996067613,7.774307862855494,3.458382107783109,0.21459681214764714,5.651148806791753,8.170698226895183,3.793332518544048,3.538043680600822,5.262194804381579,4.906901775393635,7.565307286567986,0.5521937622688711,3.6833292455412447,3.1848908960819244,3.247706927359104,4.195517904590815,2.6592070376500487,4.42317585228011,9.517835441511124,3.8378226244822145,4.352589515037835,2.377250143326819,3.605512287467718,3.783397921361029,8.00054794875905,6.7187818652018905,9.887720327824354,8.047464538831264,1.3808186585083604,1.1643479787744582,3.2511105993762612,7.0645455829799175,6.015346504282206,3.0592047097161412,0.11540454113855958,8.06422257097438,8.150190676096827,7.356889457441866,7.555075858253986,8.846610595937818,2.7350123319774866,2.8688491880893707,5.752881758380681,4.483968471176922,3.128918393049389,1.8225139006972313,7.320002722553909,7.310214806348085,3.1840061768889427,7.529367180541158,3.4418908250518143,0.6517991703003645,6.738502050284296,8.91559086740017,6.276790397241712,2.616307910066098,6.629365314729512,5.17618608660996,9.019755569752306,8.813637949060649,1.5809390135109425,8.608846133574843,6.297092293389142,3.366280284244567,3.6157000600360334,7.385678398422897,3.0267058545723557,4.512188772205263,8.192399628460407,9.405485524330288,9.259929498657584,7.286311434581876,3.183465248439461,4.278770429082215,5.716953268274665,0.5789715587161481,3.8978533656336367,2.7586988173425198,5.059975730255246,2.3651492060162127,7.258396679535508,8.921859709080309,0.7392698503099382,5.230259886011481,7.899435206782073,4.09611314535141,4.389314744621515,1.6261946968734264,5.482187354937196,3.619761881418526,6.7433681595139205,5.937277122866362,7.241670216899365,3.9092640252783895,3.0374779948033392,4.2955951928161085,6.564467148855329,3.4312051092274487,7.994420470204204,8.576327294576913,9.310934916138649,4.1444108029827476,4.47236706269905,4.259377422276884,2.6667816913686693,2.4589728680439293,7.630906035192311,0.9030878497287631,0.8322572009637952,4.516582794021815,6.804379390086979,6.603685477748513,8.616967084817588,9.897620112169534,3.538529332727194,6.723157810047269,9.502576938830316,1.928999195806682,1.8021492660045624,0.3319901507347822,2.830298824701458,1.7497945064678788,8.641119801905006,6.753190960735083,5.087939640507102,0.24097285699099302,7.77379872975871,0.07630433887243271,5.831179551314563,1.980308259371668,9.021186453755945,6.7430946649983525,1.1699359631165862,4.425695182289928,4.411204196512699,0.436347268987447,0.016210493631660938,5.219610997010022,1.8238594755530357,4.391072562430054,1.6635660687461495,2.327323257923126,3.8895407621748745,0.34937486285343766,4.997782437130809,1.470987843349576,5.134017190430313,8.724819300696254,8.439850499853492,9.617690306622535,8.46617536386475,5.261317393742502,5.368968558032066,0.63983608270064,2.8225722163915634,8.938500019721687,7.147181977052242,8.128877335693687,9.535556964110583,3.1864461838267744,6.488277849275619,9.002741042058915,9.926652549766004,2.017675314564258,1.8869244935922325,7.829469197895378,9.87749854568392,8.060033479705453,7.224856070242822,1.2798929936252534,2.78866914100945,2.915852377191186,8.727970635518432,0.10094035184010863,1.2769153341650963,9.917198012117296,3.9630167349241674,4.305270852055401,0.39072010898962617,1.4237130340188742,7.404117160476744,2.124632552731782,5.738911542575806,8.455500639975071,0.3971548075787723,0.38380363257601857,7.651389359962195,1.1605408694595098,9.019916146062315,8.391325266566128,0.2516297739930451,3.871866795234382,9.364075737539679,8.019426786340773,1.9251802214421332,1.6824836819432676,4.3521748832426965,6.440906967036426,5.670455403160304,9.13355672499165,9.674578139092773,3.551772041246295,4.358341677580029,0.5826962715946138,4.618741385638714,3.46079527400434,6.279087632428855,5.707049502525479,1.2955440115183592,3.9778111944906414,6.086649831850082,3.367316094227135,7.954099648632109,9.675174430012703,2.9813746945001185,6.1050392431207,9.072706694714725,1.0152084473520517,5.0129653653129935,4.4952176278457046,4.828229963313788,2.80279049417004,9.726273817941546,8.393716011196375,2.9691689158789814,0.5977230123244226,3.2966522267088294,1.9834079663269222,2.443813297431916,9.3139135860838,9.593252062331885,9.561771580483764,4.565526058431715,3.565698068123311,2.93719359440729,0.23579740431159735,8.647503587417305,5.528719199355692,3.2021239260211587,1.8626428116112947,7.162086877506226,8.009240166284144,2.8634931123815477,1.7266137595288455,1.3530070381239057,6.1247731652110815,0.39224540116265416,5.389998119790107,7.785557424649596,2.0238707633689046,4.911097213625908,9.156511554028839,7.698650665115565,5.17227322794497,1.703380816616118,0.2752389758825302,8.36603713221848,4.027513647451997,0.5095890816301107,2.6868695090524852,0.8549958374351263,8.37044699350372,0.1689472864381969,9.155438302550465,1.979340200778097,3.9153014589101076,8.676073581445962,7.258209879510105,5.105281511787325,0.33225199673324823,1.6601247829385102,0.5513627780601382,1.5807324997149408,7.9406681773252785,1.7205733619630337,9.603691045194864,2.8630179027095437,4.047275122720748,9.35481598135084,5.894196014851332,8.898273101076484,1.2117962702177465,3.427451769821346,1.6751115024089813,7.450441187247634,6.333751284983009,9.191068122163415,4.751952183432877,6.507860643323511,3.5455762362107635,6.3690619939006865,3.579293512739241,0.19884062465280294,9.890686634462327,9.903192091733217,1.2413786933757365,5.322804823517799,8.168133283033967,7.936764496844262,5.9427399933338165,0.9801914123818278,5.634015267714858,6.3429148006252944,1.7967454460449517,2.8216620441526175,9.046308181714267,7.734155275393277,6.892145269084722,0.04080339800566435,2.1992984949611127,1.3171452400274575,0.32386996783316135,8.644907760899514,4.66755909146741,3.7622552318498492,2.125490119215101,2.8469666210003197,8.956255142111331,1.2864466197788715,5.9537597838789225,7.54667735658586,9.981639247853309,6.530319538433105,1.8452655454166234,2.3217288847081363,2.8669062978588045,7.299607910681516,3.280770897399634,8.299202625639737,5.9492160845547915,4.460666803643107,3.553754521999508,5.6664344016462564,9.560894852038473,5.347238974645734,0.3324538213200867,5.212724609300494,4.806412188336253,5.222975553479046,1.4713243208825588,2.8643993102014065,8.965555771719664,9.282951881177723,1.2171179172582924,4.608287604060024,0.5520726274698973,8.675954404752702,7.713990451302379,0.13574847718700767,3.2274405867792666,8.782945298589766,6.04509849101305,8.638825516682118,4.733543619513512,4.097544157411903,3.721517384983599,4.021191922947764,6.29044895991683,8.46637294627726,4.789086079690605,8.02990790689364,7.917316320817918,1.7982503399252892,9.051917910110205,9.219823577441275,8.304803299251944,6.587984832003713,0.4525634692981839,9.205476662609726,8.69195195613429,3.133157326374203,7.33994496287778,4.329452724196017,1.176558828447014,6.435436676256359,9.529366253409535,5.608214184176177,5.422785482369363,4.287649565376341,8.058759570121765,8.239792054519057,4.051151594612747,8.468851919751614,6.68550766305998,4.970433753915131,2.0520593179389834,9.25285060191527,9.765314108226448,9.101411416195333,2.4982762103900313,2.5175985251553357,1.5851920936256647,3.5294777341187,1.9903180748224258,7.282198499888182,1.450364924967289,1.4495945163071156,4.4885895238257945,6.970178484916687,3.228607119526714,9.508843086659908,5.969138853251934,9.360267603769898,8.201031668577343,5.504413950257003,0.444363160058856,8.794365208595991,6.478337696753442,3.0571653158403933,4.69496059929952,8.5105563653633,5.721606253646314,3.770676008425653,7.1668785670772195,4.977014765609056,5.109445441048592,9.161017963197082,2.3393165739253163,4.160092850215733,5.534558251965791,5.571234594099224,5.829149051569402,3.7799159716814756,4.490721246693283,2.9286981048062444,7.837946303188801,9.09732264932245,5.284380256198347,6.569127740804106,0.14224236132577062,0.7112566940486431,3.2313932687975466,8.649088197853416,6.337066187988967,0.8665623585693538,0.5975108221173286,9.225046874489635,7.021017279475927,3.03283863235265,0.8192361425608397,1.8364296993240714,6.679474604316056,9.500770999584347,5.6698150699958205,0.469330467749387,0.5351261119358242,2.210079834330827,8.722575556021184,6.498342743143439,1.0846159583888948,3.6406051204539835,2.385515032801777,6.760069322772324,5.329264551401138,8.447717593517154,5.750391592737287,4.457062541041523,2.397960973903537,1.4404313871636987,0.9434649487957358,3.8073990773409605,0.8290260541252792,6.076578572392464,2.889620845671743,1.7025700793601573,7.7888068510219455,5.125095532275736,2.25424395641312,2.3183451360091567,3.9721389510668814,0.41902625001966953,9.24581942614168,8.262916828971356,3.315193944144994,5.921145835891366,0.035002054646611214,7.369782589375973,4.383812777232379,5.889177967328578,9.923857869580388,2.355423846747726,2.95550178270787,3.789925987366587,8.410550525877625,9.414464952424169,8.00936208339408,0.7033347873948514,1.8303936417214572,5.814342319499701,9.248531309422106,4.3787982617504895,0.6746661965735257,1.053044784348458,8.336823675781488,0.29698571190238,9.174948441796005,5.18295472022146,1.4739059610292315,0.9499002108350396,6.4988583931699395,5.646643748041242,4.88169884076342,8.310269580688328,3.4229141660034657,4.430989425163716,9.839584520086646,4.932196433655918,9.598212733399123,4.078633387107402,2.124364417977631,6.205928954295814,1.1621719202958047,2.075500339269638,5.247691301628947,9.616502453573048,0.8466748869977891,1.3727407669648528,3.2300059543922544,3.7397971469908953,6.974140224047005,7.605024427175522,8.858814416453242,3.0201582750305533,8.513688761740923,6.1404573218896985,9.818810618016869,4.814249349292368,3.586849682033062,5.691904278937727,0.08578629698604345,8.12171152094379,0.2463038545101881,0.631671582814306,6.405444687698036,1.247334333602339,5.87713137967512,7.142814432736486,4.084130122791976,5.3019098727963865,0.6986237247474492,5.578774176537991,6.922094707842916,3.1462549371644855,5.241006824653596,7.232290639076382,0.6026483443565667,1.3768058666028082,0.08003556169569492,3.056485091801733,0.36391520174220204,9.648529915139079,0.8321366808377206,4.8639202932827175,0.04729584092274308,4.557534940540791,8.954018091317266,2.728234075475484,3.9430438703857362,8.676431993953884,7.024349491111934,7.706452382262796,7.474976892117411,9.013208753895015,3.983901480678469,3.2532308739610016,3.856631957460195,0.6799420155584812,4.071933226659894,3.9262308925390244,3.7392733758315444,1.5917768306098878,0.279220484662801,1.5261770808137953,6.645503242034465,7.39584710681811,5.803650752641261,4.92629227694124,3.2169264694675803,4.9417629931122065,6.19889791123569,1.5975867537781596,8.312263281550258,0.14834391651675105,2.029930637218058,6.402105689048767,6.113263389561325,1.985282285604626,2.505738395266235,8.142135050147772,8.030197187326849,0.9432496968656778,3.553340518847108,1.2001235736534,7.0014568767510355,0.8712048991583288,7.218146389350295,3.108048194553703,0.5959121184423566,8.937904289923608,4.43502742331475,5.265623216982931,9.983510402962565,7.959266698453575,6.320372137706727,6.3003423204645514,5.463160099461675,3.3636903017759323,8.07415701681748,6.806202935986221,8.266241094097495,5.370127386413515,6.115587130188942,3.5212122928351164,3.627032130025327,9.335073630791157,0.2766379411332309,3.4970815549604595,6.336682494729757,1.0654873517341912,2.2779573663137853,7.545566235203296,5.954197410028428,5.806731297634542,4.015602404251695,9.525050513911992,4.77150441147387,2.7979273931123316,3.2749838870950043,9.45563584798947,0.09879812132567167,2.4449413153342903,5.518020107410848,6.296010280493647,1.592619251459837,6.327643119730055,3.2402966916561127,7.0537514868192375,1.5324516058899462,5.881986066233367,6.6874419478699565,7.011232525110245,5.271969200111926,6.413867732044309,8.923816692549735,9.083089362829924,7.67493249848485,8.792618461884558,1.5498139732517302,4.922635336406529,6.5072737680748105,5.22849471308291,5.351687946822494,2.0744572672992945,7.13923693401739,5.409126812592149,0.9846348548308015,9.132452446501702,9.788705580867827,7.06255468307063,4.379081064835191,1.459092313889414,8.872436513192952,7.824255577288568,1.9047077163122594,5.91305744368583,3.95631808321923,8.415001172106713,6.593160284683108,9.465731894597411,1.5623756009154022,7.231087188702077,7.968563807662576,4.240919598378241,9.750124081037939,9.57732462324202,5.524232855532318,8.876056729350239,5.419644471257925,3.8573184912092984,8.71060271281749,7.383526682388037,2.6232833857648075,2.167216648813337,0.6891097198240459,1.5929507254622877,7.552667181007564,6.112799821421504,3.2445063162595034,5.761312402319163,1.4269530004821718,6.757629525382072,9.055622359737754,4.490635963156819,3.005405543372035,3.1100730877369642,3.336475242394954,9.020458811428398,6.665812183637172,0.5622236523777246,0.24418123299255967,6.458999204915017,9.113601909484714,5.332121967803687,9.051467652898282,2.5377386272884905,0.06617928855121136,8.953536252956837,9.625905477441847,9.871210381388664,0.06093396572396159,5.500918184407055,6.136398678645492,3.455249024555087,7.022403746377677,4.186076687183231,9.447183585725725,0.7258855388499796,4.193982670549303,4.073762791231275,3.48527958849445,7.124344191979617,7.4344271956942976,2.058891821652651,6.108035012148321,9.700778108090162,7.40551418159157,4.405704005621374,1.5880355378612876,8.668289298657328,0.9236494894139469,0.5630778265185654,4.675268935970962,7.89153668563813,8.95357889123261,1.1104525881819427,1.114057411905378,5.148262919392437,2.8109398880042136,8.986127427779138,4.742131666280329,1.729847362730652,2.5206953077577055,4.106387132778764,9.701968322042376,7.759640198200941,5.740222258027643,0.24120857240632176,1.4410786493681371,8.009897889569402,8.936529501806945,0.9522559540346265,3.43249773606658,6.40288537601009,3.234312899876386,8.333164108917117,3.9870322681963444,0.91971087269485,5.128620658069849,2.376817553304136,1.0331127932295203,8.431752701289952,3.8787931436672807,7.11586213670671,5.129346714820713,9.439627323299646,2.730485238134861,3.1133452500216663,7.389392589684576,2.136833011172712,6.702913187909871,9.67047925805673,1.3177918968722224,8.438838790170848,5.005237511359155,0.18251155503094196,4.0377202443778515,6.433610245585442,3.1418353994376957,0.7609018008224666,3.2746874215081334,9.826047737151384,2.9710332467220724,7.243791192304343,8.390633163508028,4.1798886633478105,3.875475013628602,6.680055041797459,5.404357824008912,7.209625213872641,0.32174521358683705,0.5552434921264648,4.398770937696099,9.327740897424519,1.0799965169280767,0.782781180460006,6.297578073572367,0.9427543310448527,5.402197553776205,9.3627410242334,4.048871209379286,8.352442337200046,0.6531258439645171,8.322408152744174,0.4232423333451152,8.529539406299591,8.878272820729762,9.475544735323638,9.252802892588079,3.4703456796705723,7.412700990680605,6.745369881391525,8.362561122048646,9.61106286616996,9.246906617190689,1.7375518730841577,5.280082421377301,2.023140504024923,0.27117491932585835,8.990772373508662,2.1041698241606355,8.830703268758953,5.421146000735462,8.241722732782364,3.047999022528529,8.589261856395751,9.114171438850462,2.89663860341534,7.77944823494181,8.405141171533614,2.2412185254506767,1.1118765827268362,0.15475268010050058,9.219623620156199,2.3388031870126724,6.74962900346145,7.11000258103013,8.58264237176627,9.65570705709979,2.777035520412028,9.163185663055629,2.1187206404283643,7.487841993570328,0.7285763695836067,3.8358826097100973,4.958077329210937,3.3186359121464193,7.494144381489605,9.805061717052013,1.4622714277356863,1.2707394803874195,7.372791413217783,6.766709061339498,5.220039028208703,2.0707297744229436,7.155217160470784,9.567439665552229,2.1715411194600165,3.0287244147621095,2.0935479691252112,5.7181795057840645,1.3374383770860732,1.4437670982442796,2.229987601749599,5.629292957019061,4.438080200925469,2.8963091038167477,3.2311262539587915,9.258770167361945,7.682583821006119,0.3442920558154583,7.52879191422835,4.285130866337568,3.3373237471096218,3.9863606193102896,2.7974618948064744,0.5093348119407892,8.161671336274594,3.6710569192655385,0.15639419667422771,4.785774836782366,4.371580411680043,5.59470092644915,4.196186689659953,3.5285426396876574,7.624466461129487,7.821976104751229,7.641605953685939,4.090073329862207,9.302951826248318,7.207879973575473,4.920398378744721,9.290684608276933,5.774778400082141,0.8102608169429004,6.003749766387045,9.865081324242055,9.61276046000421,7.548458769451827,0.2787048486061394,3.6695049051195383,7.046924394089729,4.78735726326704,0.690148170106113,1.3847953011281788,1.3659868156537414,5.81805907888338,6.036841187160462,7.247420330531895,0.5867991875857115,7.918846395332366,4.816894670948386,9.760163868777454,3.761894265189767,9.604116266127676,3.8879027497023344,2.645444783847779,6.8812884646467865,3.4451603051275015,9.480039989575744,6.96180027211085,9.176043886691332,3.7707790383137763,7.432482750155032,7.664772956632078,7.793930487241596,2.525892131961882,8.50616543320939,0.7726947125047445,7.132422402501106,0.2727644005790353,6.206431726459414,9.707880192436278,4.99498043442145,7.618717472068965,1.5810609725303948,9.91091194562614,8.336031804792583,3.2491677603684366,0.02873112913221121,7.427574023604393,8.33627390442416,1.8594216601923108,1.4347189757972956,6.475316963624209,6.393060914706439,2.149796923622489,0.39602426113560796,9.804883578326553,5.756679147016257,7.7590328035876155,6.275271084159613,0.6845211144536734,6.302854046225548,8.503771356772631,0.6995680904947221,4.595206868834794,5.739592604804784,8.902673011180013,0.3918302967213094,7.799455195199698,0.6336134648881853,0.5764604662545025,0.6564780650660396,4.466231181286275,0.36326027708128095,0.979608295019716,5.016129771247506,3.0382750369608402,2.7278555394150317,9.505183058790863,4.730000076815486,8.81509207887575,9.661492721643299,2.2802249807864428,3.856866725254804,2.2590105165727437,1.1880779056809843,6.36979965493083,6.863516794983298,5.471703454386443,2.6916230213828385,4.49135904898867,7.960270547773689,9.18560468358919,0.405365030746907,3.940486554056406,8.994000100065023,0.286626061424613,9.060897070448846,8.880923427641392,5.6295722420327365,5.595777346752584,7.790995810646564,6.640329139772803,3.8866658601909876,4.392917102668434,0.81801469437778,4.092508296016604,1.3150955270975828,3.2104334188625216,3.343771027866751,0.7922920188866556,7.467067881952971,2.7943023410625756,7.35004672780633,8.955614177975804,0.6924187857657671,2.9766863374970853,2.982900079805404,5.149163547903299,0.7587808021344244,5.495809055864811,9.895763201639056,1.9980297749862075,5.680950589012355,0.2833250258117914,5.160863287746906,3.3061955450102687,6.126706663053483,5.092719225212932,3.471996681764722,0.40845570154488087,8.809545852709562,0.41240135207772255,0.7007679459638894,4.644989185035229,5.402957273181528,3.1835155142471194,8.874168668407947,2.0051661506295204,3.6553915264084935,3.342277437914163,0.7016782579012215,0.5557832703925669,2.1724525978788733,0.7305986527353525,5.11548722628504,5.323966674041003,5.280183479189873,9.296258958056569,1.8281864933669567,1.5077325911261141,0.6386737897992134,9.896054649725556,3.431777728255838,5.652669246774167,0.6770251714624465,2.5347269605845213,9.633591913152486,5.160807867068797,5.913102389313281,2.7730581490322948,7.716303537599742,1.0102198226377368,7.50285963062197,1.408177672419697,1.2599345133639872,1.4842764963395894,7.365092723630369,6.716901049949229,1.1312897270545363,8.296968115027994,9.103325819596648,8.576687227468938,4.2583829700015485,2.8992986981756985,4.522206841502339,0.5454922490753233,4.334308826364577,6.173307211138308,8.580648149363697,1.752965326886624,1.5858782338909805,0.2874048752710223,5.118917291983962,9.330119474325329,2.407601298764348,5.6703683151863515,1.7356508830562234,0.12674539349973202,1.2370011419989169,5.223798463121057,8.840755166020244,8.223172936122864,1.0479398723691702,9.127157032489777,5.0065735867246985,0.5894318339414895,2.6026442064903677,1.0727001912891865,3.677814626134932,0.6211163615807891,7.065325311850756,4.799406565725803,3.754234549123794,2.2943412489257753,0.1220970693975687,4.260414750315249,8.183126414660364,9.949804465286434,5.601314960513264,4.251789464615285,5.660751860123128,0.7730075158178806,4.006620328873396,7.100624938029796,9.826707723550498,7.9794110474176705,2.929651269223541,5.5398171790875494,2.1196571947075427,7.389518632553518,3.0125506641343236,7.995314311701804,0.309637226164341,9.109576425980777,4.850033402908593,5.836737265344709,8.567279109265655,6.991376981604844,4.719556211493909,9.211067028809339,5.137387553695589,9.19474045978859,6.912961232010275,5.466075958684087,4.419572269544005,6.171108540147543,9.810278152581304,0.772656574845314,3.3136177016422153,2.920890736859292,9.491652071010321,2.2066241479478776,0.5756494379602373,7.154275856446475,8.238706982228905,3.5841460758820176,5.064190095290542,2.0595223363488913,2.176204938441515,5.735069885849953,0.854919170960784,7.826219175476581,6.613375940360129,1.7721033305861056,1.6580536519177258,3.311698012985289,9.709230295848101,2.0702647999860346,7.25381653290242,4.254569071345031,7.006728227715939,9.31152175879106,3.466042666696012,3.0842236266471446,5.737497343216091,5.720236881170422,0.9332084935158491,1.9149792077951133,4.2891683196648955,7.054053777828813,3.67476599290967,3.7359976512379944,2.27169266436249,3.972181221470237,9.467683425173163,0.5641223234124482,3.7870318675413728,6.858365037478507,1.3455796614289284,1.6292286152020097,4.82172760181129,7.927085501141846,0.048026570584625006,7.261468344368041,8.920171388890594,6.584138963371515,5.797392474487424,5.503258719108999,5.377397791016847,9.180650466587394,7.6735916174948215,2.3314723069779575,5.271672031376511,4.652883606031537,7.2418782860040665,4.006839310750365,8.904543151147664,5.700144928414375,7.253411856945604,5.508117189165205,4.310129103250802,7.256692026276141,9.490583406295627,3.8978980178944767,0.8199827093631029,2.2928559873253107,8.633115680422634,4.007787087466568,2.536181048490107,9.142198492772877,7.274342041928321,7.062257567886263,4.6163533721119165,5.775722260586917,1.8128746724687517,6.125398916192353,0.9765034425072372,8.069729937706143,0.1609800406731665,6.871428689919412,0.12279951944947243,1.5686771203763783,9.641415146179497,1.5150466677732766,3.623195600230247,3.252211317885667,2.843856813851744,2.111335073132068,6.072979089803994,5.391069953329861,0.28139691799879074,3.9535815501585603,3.1713187973946333,8.895994999911636,6.296534081920981,2.293499584775418,2.010152053553611,7.317216149531305,2.750641289167106,0.3282890049740672,1.297422694042325,7.787100598216057,5.976826881524175,6.2007618509233,8.133389616850764,7.342623786535114,0.3353470587171614,0.1401476445607841,0.6348051363602281,5.62640700256452,6.834628670476377,8.287429567426443,8.760479835327715,2.464153717737645,9.948190136346966,7.518533570691943,2.483075982891023,9.525565390940756,8.28531475737691,7.446576666552573,6.379745360463858,8.449977647978812,9.502119636163116,9.166164598427713,1.84962299419567,2.5214252551086247,9.474943114910275,7.480313575360924,9.18577824253589,9.574639580678195,3.0873931501992047,3.902828844729811,8.955786465667188,1.822055319789797,1.2770397728309035,9.003044599667192,8.232472618110478,4.205495140049607,6.678732584696263,9.705365237314254,3.303111109416932,1.6291389521211386,4.670131162274629,4.783018177840859,7.774069514125586,6.918880138546228,0.0847647269256413,7.310405981261283,6.046568390447646,4.71660397015512,8.759698749054223,9.162689112126827,4.724578890018165,8.798923729918897,3.4097588481381536,9.658417680766433,0.8257632004097104,9.154552412219346,1.7069766810163856,2.0297640305943787,0.32220604130998254,8.870249604806304,0.8042637398466468,1.6107536456547678,2.870572868268937,1.927663697861135,1.8293870287016034,6.638193135149777,0.15985927311703563,3.469282186124474,4.662023081909865,6.822183250915259,0.07973068626597524,5.27177037904039,9.602021172177047,0.3938668267801404,4.24152075080201,9.488032115623355,3.5663137235678732,6.400670511648059,8.659203653223813,1.9419052777811885,6.476652035489678,2.5672774179838598,8.872400331310928,6.980321214068681,0.5659185512922704,5.1587631017901,0.16739953309297562,0.3771748370490968,9.78439987404272,4.459752687253058,3.7111810967326164,2.431070290040225,7.674493484664708,5.543658756650984,6.178148351609707,1.1710951244458556,8.90641275094822,3.944787213113159,3.161431953776628,6.2640175595879555,3.0730902426876128,6.702820162754506,4.11391464760527,1.9151894887909293,9.35838958248496,2.217791029252112,7.806389082688838,5.219341707415879,9.116828937549144,7.963402427267283,8.572508585639298,3.778735229279846,7.3732008738443255,3.7390939285978675,0.4619262972846627,1.9791384623385966,8.00595281412825,3.56250875396654,3.9490386354736984,4.621090982109308,7.616894841194153,9.411722305230796,8.994079555850476,1.8118510814383626,4.475696457084268,6.3445988786406815,9.355857539921999,9.537861722055823,2.563942053820938,0.4753952892497182,6.078333002515137,4.1584666282869875,2.1797239361330867,0.4499889397993684,7.546788947656751,3.326692469418049,0.4163886094465852,8.180438366252929,2.8719682176597416,8.853986996691674,1.7794578382745385,3.3300268999300897,2.240218697115779,4.361645104363561,8.770431957673281,4.937058859504759,1.312054772861302,6.286779607180506,1.4903844916261733,6.811417683493346,0.5334125878289342,3.3075830689631402,3.416214669123292,3.838753046002239,0.7749398867599666,9.048466596286744,5.261005235370249,2.0465035107918084,8.26013441896066,9.483851396944374,7.31332222931087,1.1874781618826091,6.626302050426602,9.710194584913552,6.238884350750595,8.566150898113847,6.191658522002399,0.16678494168445468,2.9975258465856314,0.40159796364605427,9.024084887932986,2.067894882056862,1.7542802216485143,9.287410946562886,7.035958676133305,8.388541280291975,5.0866307923570275,9.088220556732267,3.737106502521783,6.08713440829888,4.694471629336476,8.658810071647167,4.736885798629373,5.443868017755449,0.21531900856643915,4.328751866705716,8.734100982546806,9.691879767924547,0.6026311591267586,5.0918229622766376,2.414504252374172,0.6562796025536954,8.007745193317533,4.561325695831329,6.4563240320421755,1.0674994997680187,3.437700199428946,7.750045235734433,4.608365250751376,6.1000909633003175,2.6345350174233317,8.13884753268212,3.695160890929401,9.056671024300158,9.669701177626848,6.6390090505592525,4.195509182754904,9.878272323403507,5.170153737999499,8.852205644361675,4.537872176151723,7.302804717328399,2.996683830861002,0.0850060279481113,0.39945898577570915,1.2676188396289945,9.220832276623696,7.742931165266782,5.870538945309818,9.997982932254672,3.707713894546032,0.5426692753098905,5.312947144266218,6.040325423236936,8.903734616469592,3.7200537347234786,8.87317496817559,8.910572861786932,1.374665042385459,5.452206975314766,4.963398557156324,3.448840258643031,5.863132041413337,6.359814011957496,7.869354677386582,9.31053961161524,0.4624076629988849,0.50285620149225,7.374885943718255,3.4966174489818513,6.466078041121364,0.6122018559835851,9.153956223744899,2.585089879576117,3.510377111379057,6.071923410054296,0.6867449101991951,7.3726611328311265,6.147802732884884,9.609369693789631,2.1416593273170292,4.45459084585309,6.082902064081281,0.30924258986487985,5.090798798482865,7.6942396513186395,3.8768380135297775,2.0571266440674663,3.0510861054062843,6.114556828979403,6.145044157747179,9.76746681611985,1.452829330228269,1.8749052751809359,6.703981806058437,8.41798685491085,7.54781034309417,5.306985436473042,7.160931697580963,5.725655315909535,5.888903685845435,4.721376013476402,5.848252370487899,9.98144534882158,1.8746388657018542,7.232015256304294,7.117245784029365,1.855696034617722,1.3886801432818174,9.305877354927361,2.219520155340433,6.130027202889323,5.434409484732896,9.368655756115913,0.010560411028563976,2.909986381419003,0.8472597342915833,5.535500969272107,6.497512315399945,3.22523461189121,8.036356137599796,1.1022535758093,1.9288622331805527,1.5512380236759782,0.8913211128674448,4.4428992457687855,5.222196257673204,6.0349663882516325,4.319484701845795,0.2740642870776355,7.4866299401037395,6.5149042825214565,1.8699029320850968,1.224007597193122,8.709125821478665,0.8581114909611642,7.208434175699949,0.2330804825760424,8.256173769477755,2.999106957577169,1.4772750926204026,3.076366998720914,8.800826682709157,5.014731714036316,8.033633518498391,9.080262936186045,3.056185571476817,5.205376564990729,1.0332584264688194,2.947180198971182,3.553388479631394,7.335517478641123,9.405087830964476,8.324133488349617,2.8369443770498037,4.569727415218949,0.0028109620325267315,4.491785375867039,4.181515297386795,8.579165309201926,9.589058754500002,5.710007438901812,0.7714147912338376,7.076025784481317,4.897682091686875,3.109375536441803,8.52890222799033,0.8067928743548691,3.339387560263276,2.7486888831481338,0.1834739069454372,0.13786843745037913,9.225133599247783,4.104528869502246,6.718224517535418,9.042769731022418,6.782753930892795,6.359363845549524,3.2467037439346313,6.956676165573299,1.002732792403549,7.878509892616421,6.505595904309303,3.9875898300670087,9.472178118303418,0.033289180137217045,2.1123246382921934,6.898302035406232,2.790963838342577,5.609240636695176,6.547042510937899,7.332089270930737,1.687012780457735,9.050792825873941,4.550500046461821,2.508453610353172,8.34862070158124,0.5174473067745566,2.365494992118329,7.8418893297202885,7.949061542749405,5.1846180856227875,4.135512995999306,6.027367771603167,8.786611303221434,7.2287139017134905,8.400008329190314,5.652564191259444,6.485898280516267,1.5929361968301237,3.3511886931955814,6.965320943854749,7.1733984421007335,6.4590505650267005,3.3780623809434474,2.53732934826985,7.090107607655227,4.937354400753975,0.1462509809061885,8.326996385585517,6.020387683529407,8.211010524537414,0.6880706432275474,6.092719400767237,7.7066361997276545,5.124120262917131,8.530900250189006,3.191711043473333,7.281458636280149,8.541571113746613,4.788106638006866,0.8656909805722535,9.950766898691654,3.775679904501885,6.872359309345484,6.466396288014948,5.735910239163786,6.930676903575659,0.028583097737282515,6.362798169720918,3.401729306206107,1.8991571152582765,9.183174695353955,8.527052854187787,3.920709218364209,3.9081501052714884,0.5026421789079905,8.57710946816951,3.2544350367970765,8.381201976444572,6.014232321176678,2.2734661516733468,3.884390089660883,7.168968559708446,3.1055986578576267,0.8504488063044846,0.6574258208274841,1.9687496963888407,1.2488291063345969,3.9164828951470554,3.5668431571684778,5.303401290439069,3.556828510481864,8.636603229679167,2.2163238376379013,8.328525421675295,7.96512397704646,2.508733293507248,4.877198901958764,1.696917014196515,5.875644078478217,1.0215720790438354,7.742140111513436,3.8253072323277593,3.827912879642099,5.0153932883404195,8.497627591714263,9.051827022340149,6.663935126271099,2.6890286710113287,4.635762011166662,2.8451002947986126,1.317774683702737,3.7477840180508792,7.005943777039647,6.863876138813794,8.196028764359653,2.796280402690172,2.1653333492577076,0.3082891320809722,5.177921887952834,9.081181653309613,5.503672880586237,3.022115209605545,8.704451217781752,8.409341319929808,5.449645619373769,8.13090322073549,4.612170911859721,4.974079809617251,8.63246324006468,3.6019188771024346,4.883304922841489,8.410894167609513,0.1754862884990871,6.9699426321312785,6.449795283842832,3.2386696618050337,6.872938610613346,9.560737845022231,8.015959477052093,4.820810530800372,5.76675301650539,5.969588891603053,9.71083827316761,6.270281868055463,6.4288035640493035,4.540399077814072,1.238783011212945,2.70120911533013,2.455858471803367,9.08755749464035,7.42733390070498,0.16459927195683122,7.792567100841552,5.340316668152809,8.550936542451382,3.6319944611750543,2.0526350010186434,8.638602651190013,2.9231304302811623,5.132332989014685,6.8238003039732575,2.972788519691676,4.986278247088194,8.902562253642827,9.726327853277326,2.4262788868509233,5.7048242329619825,0.4887069808319211,6.045272841583937,4.690704664681107,0.3353210841305554,8.006177013739944,8.680784935131669,2.0461021014489233,8.06122918613255,5.95336735015735,0.6149334507063031,3.381724094506353,9.917126761283726,7.5794518971815705,9.861289612017572,8.255028801504523,6.40686403028667,2.1936482144519687,4.350684678647667,2.186387076508254,4.124441018793732,5.135223595425487,8.044509517494589,8.714396869763732,1.286247547250241,2.401028040330857,3.2922549708746374,8.839298854582012,0.4996850760653615,0.7018996053375304,0.4600142454728484,3.947083200328052,2.629854765255004,5.5269017606042325,3.641773136332631,6.171250171028078,7.958270467352122,4.345328859053552,4.113983828574419,8.228186129126698,3.1365121947601438,0.8844565250910819,5.231514738406986,7.216556174680591,5.046960632316768,3.8190950616262853,0.15302482061088085,0.6978752231225371,4.3839905597269535,3.090344632510096,5.431912227068096,1.5771419298835099,0.29228524304926395,6.4315836620517075,0.27367391623556614,7.62010051170364,3.9641580637544394,3.18216466344893,1.7433763318695128,4.4212109060026705,5.803502427879721,7.126736051868647,2.236764603294432,9.896282262634486,3.6362336203455925,0.49861375242471695,0.4306951235048473,2.2750253067351878,0.9063962195068598,2.074180683121085,7.293821016792208,2.682933029718697,8.858296943362802,6.768294712528586,5.607374026440084,6.985351680777967,5.849818694405258,4.769126872997731,3.676380175165832,0.9810877963900566,5.216674394905567,3.2992141181603074,4.397831300739199,8.939810239244252,1.2864493671804667,1.070280079729855,7.304996794555336,5.247464687563479,4.800995299592614,2.5238397368229926,9.333614155184478,7.904198162723333,5.857936444226652,6.983835839200765,0.12860742630437016,4.067891526501626,5.004377830773592,7.81127599067986,7.552224041428417,8.087909475434572,9.61275911424309,6.355922950897366,1.997298183850944,2.147095089312643,7.587601693812758,0.3507608105428517,3.214240816887468,0.4481401271186769,8.558716361876577,4.226938223000616,3.3966982550919056,0.6860379711724818,0.5942504829727113,2.0161200338043272,0.008770730346441269,1.1269167135469615,1.1443942948244512,0.9506070939823985,2.6806247606873512,3.1751575088128448,7.550022893119603,0.5481684347614646,3.276002479251474,0.6785353692248464,9.754259421024472,9.442907175980508,8.390649778302759,7.125653347466141,4.137831430416554,9.08945154864341,5.778692571911961,3.945129052735865,1.3508908171206713,9.102336601354182,4.092890555039048,6.171590136364102,8.539728224277496,5.201710297260433,4.250538183841854,7.666936442255974,8.03294611396268,3.0906258476898074,3.6614765995182097,5.1746382471174,7.280544408131391,8.87948032002896,3.523988991510123,8.768577789887786,0.548009283374995,6.644843064714223,1.0905100358650088,5.908335722051561,3.8091140962205827,1.489883647300303,1.9381182617507875,5.468435357324779,4.856602211948484,1.9279759982600808,0.9892736119218171,0.41426529875025153,9.646270943339914,8.78195498837158,7.620176488999277,7.033941438421607,6.100081659387797,9.584738134872168,7.6452151709236205,8.710821862332523,3.31917988602072,5.510850565042347,3.8572997669689357,3.1595066795125604,9.054107670672238,6.999417408369482,9.843484414741397,8.839693872723728,4.4175667013041675,9.71137325745076,3.5052315215580165,1.8646901124157012,5.584472434129566,8.079652560409158,4.316841347608715,0.6563068926334381,4.355958045925945,7.952115361113101,1.612688945606351,0.6541568553075194,3.6283174948766828,3.6298038600943983,5.129724673461169,8.923856501933187,4.301771363243461,0.43236425379291177,6.794311958365142,8.65310367429629,1.4601672533899546,6.09687692951411,4.598260552156717,5.100484711583704,9.669725431594998,1.8093775934539735,8.658116031438112,8.355668031144887,1.1881286883726716,8.766729938797653,4.8027647053822875,7.902374111581594,4.165262170135975,6.765276649966836,1.3222630834206939,1.2765076151117682,6.316710694227368,2.3988837259821594,5.203518872149289,1.1172460136003792] class JenksBreaksFunctionTestCase(unittest.TestCase): """ Test the behavior of the `jenks_breaks` function : - errors on bad input - correct results on valid input - works when using numpy array or list as input - old incorrect results no longer occur - etc. """ def setUp(self): self.data1 = test_data self.data2 = [132, 915, 312, 1424, 1240, 1370, 113, 1028, 1078, 416, 963, 359, 1422, 658, 73, 1326, 245, 848, 683, 255, 1223, 253, 654, 736, 1079, 39, 583, 1367, 1237, 327, 1083, 328, 951, 678, 927, 301, 96, 297, 179, 230, 767, 1248, 1, 37, 1352, 1009, 663, 1283, 679, 230] self.data3 = [0, 1, -2] self.data4 = [2**76, 2**76, 3**80] self.data5 = [-1, -1, -1, -1, 2, 2] self.res1 = (0.002810962, 2.0935481, 4.2054954, 6.1781483, 8.0917587, 9.997983) self.res2 = (1.0, 416.0, 767.0, 1083.0, 1424.0) def test_json_ref(self): """ Breaks are correct against other implementations """ # Test it against break values computed using another library # implementing jenks natural breaks: res = jenks_breaks(self.data1, 5) self.assertEqual(len(self.res1), len(res)) for break_values in zip(res, self.res1): self.assertAlmostEqual(break_values[0], break_values[1], places=6) # Test the result is the same using a python array as input: res_py_array = jenks_breaks(array('d', self.data1), 5) self.assertEqual(len(self.res1), len(res_py_array)) for break_values in zip(res_py_array, self.res1): self.assertAlmostEqual(break_values[0], break_values[1], places=6) # Test the result is the same using a numpy array as input: data_np = np.array(self.data1) res_np = jenks_breaks(data_np, 5) self.assertEqual(res_np, res) def test_errors(self): """ Errors are raised when using invalid input """ # Using wrong 'n_classes' argument: with self.assertRaises(ValueError): jenks_breaks([1, 2, 3, 4], 32) with self.assertRaises(ValueError): jenks_breaks(self.data2, -5) # Using a wrong 'values' argument: with self.assertRaises(TypeError): jenks_breaks("a sequence of characters", 4) with self.assertRaises(TypeError): jenks_breaks(['a', 'b', 'c', 'd'], 3) # Using non-finite (NaN or Inf) values: with self.assertRaises(ValueError): jenks_breaks([1, 2, 3, 4, 5, float('Inf'), float('NaN'), 12], 3) # Same if they are in a numpy array with self.assertRaises(ValueError): jenks_breaks(np.array([1, 2, 3, 4, 5, float('Inf'), float('NaN'), 12]), 3) def test_integers(self): """ The algorithm works using a list/an array of integers """ # With a regular list as input: res = jenks_breaks(self.data2, 4) for break_values in zip(res, self.res2): self.assertAlmostEqual(break_values[0], break_values[1], places=1) # With a numpy array as input: res = jenks_breaks(np.array(self.data2), 4) for break_values in zip(res, self.res2): self.assertAlmostEqual(break_values[0], break_values[1], places=1) def test_large_integers(self): """ The algorithm fails using a list/an array of too large integers """ # With a regular list as input: with self.assertRaises(TypeError): jenks_breaks(self.data4, 2) # With a numpy array as input: with self.assertRaises(TypeError): jenks_breaks(np.array(self.data4), 2) def test_n_classes(self): """ Test the behavior of the 'n_classes' argument """ # Using wrong 'n_classes' argument: with self.assertRaises(TypeError): jenks_breaks([1, 2, 3, 4], [2]) with self.assertRaises(TypeError): jenks_breaks([1, 2, 3, 4], "a") # Using an integer as a float value for n_classes (allowed): res1 = jenks_breaks(self.data2, 4) res2 = jenks_breaks(self.data2, 4.0) for break_values in zip(res1, res2): self.assertAlmostEqual(break_values[0], break_values[1], places=1) # Trying to use a float value (that can be converted to int without loosing information) # as 'n_classes' (not allowed): with self.assertRaises(TypeError): jenks_breaks(self.data2, 4.7) # Number of class is larger than the number of values: with self.assertRaises(ValueError): jenks_breaks(self.data3, 4) # Number of class is larger than the number of unique values: with self.assertRaises(ValueError): jenks_breaks(self.data5, 3) def test_old_errors(self): """ Testing cases that are known to have caused inaccurate results in previous versions of jenkspy. """ res = jenks_breaks(self.data3, 2) self.assertEqual(res, [-2, -2, 1]) res = jenks_breaks(self.data5, 2) self.assertEqual(res, [-1, -1, 2]) class JenksMatricesTestCase(unittest.TestCase): """ Test the matrices of lower class limits returned by the algorithm we have implemented against the algo that uses the arithmetic of the original implementation in Fortran. """ def setUp(self): self.data1 = np.array(test_data) self.data2 = np.array([1, 2, -2]) self.data3 = np.array([-1, -2, -1.5, 2, 3, 2.3, 2.5]) self.data4 = np.array([-1, -1, -1, -1, 2]) def test_matrices1(self): for n_class in range(3, 7): mat1 = _jenks_matrices(self.data1, n_class)['lower_class_limits'] mat2 = _jenks_matrices(self.data1, n_class, True)['lower_class_limits'] assert np.allclose(mat1, mat2) def test_matrices2(self): mat1 = _jenks_matrices(self.data2, 2)['lower_class_limits'] mat2 = _jenks_matrices(self.data2, 2, True)['lower_class_limits'] assert np.allclose(mat1, mat2) def test_matrices3(self): for n_class in range(2, 5): mat1 = _jenks_matrices(self.data3, n_class)['lower_class_limits'] mat2 = _jenks_matrices(self.data3, n_class, True)['lower_class_limits'] assert np.allclose(mat1, mat2) def test_matrices4(self): for n_class in range(2, 5): mat1 = _jenks_matrices(self.data3, n_class)['lower_class_limits'] mat2 = _jenks_matrices(self.data3, n_class, True)['lower_class_limits'] assert np.allclose(mat1, mat2) class JenksNaturalBreaksClassTestCase(unittest.TestCase): """ Test the behavior of the JenksNaturalBreaks class : - compute the breaks according to the data provided - predict class of new data point - group data according to the predicted classes """ def setUp(self): self.data2 = [132, 915, 312, 1424, 1240, 1370, 113, 1028, 1078, 416, 963, 359, 1422, 658, 73, 1326, 245, 848, 683, 255, 1223, 253, 654, 736, 1079, 39, 583, 1367, 1237, 327, 1083, 328, 951, 678, 927, 301, 96, 297, 179, 230, 767, 1248, 1, 37, 1352, 1009, 663, 1283, 679, 230] # Result for testing fit method self.res3 = [1.0, 416.0, 767.0, 1083.0, 1424.0] self.res4 = [416.0, 767.0, 1083.0] self.res5 = np.array( [0, 2, 0, 3, 3, 3, 0, 2, 2, 0, 2, 0, 3, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 1, 2, 0, 1, 3, 3, 0, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 1, 3, 0, 0, 3, 2, 1, 3, 1, 0]) self.res6 = [np.array( [132, 312, 113, 416, 359, 73, 245, 255, 253, 39, 327, 328, 301, 96, 297, 179, 230, 1, 37, 230]), np.array([658, 683, 654, 736, 583, 678, 767, 663, 679]), np.array([915, 1028, 1078, 963, 848, 1079, 1083, 951, 927, 1009]), np.array([1424, 1240, 1370, 1422, 1326, 1223, 1367, 1237, 1248, 1352, 1283])] # Result for testing predict method self.res7 = np.array([0, 1]) # Results for testing group method self.res8 = [np.array([150]), np.array([]), np.array([]), np.array([])] self.res9 = [np.array([150]), np.array([700]), np.array([]), np.array([])] def test_calling_class(self): """ JenksNaturalBreaks class is callable with or without arguments """ jnb = JenksNaturalBreaks() self.assertEqual(type(jnb).__name__, 'JenksNaturalBreaks') jnb = JenksNaturalBreaks() self.assertEqual(jnb.n_classes, 6) jnb = JenksNaturalBreaks(n_classes=4) self.assertEqual(jnb.n_classes, 4) def test_fit(self): """ JenksNaturalBreaks.fit compute the breaks, the class of each data point and the groups of data points """ jnb = JenksNaturalBreaks(n_classes=4) jnb.fit(self.data2) self.assertEqual(jnb.breaks_, self.res3) self.assertEqual(jnb.inner_breaks_, self.res4) self.assertEqual((jnb.labels_ == self.res5).all(), True) self.assertEqual(type(jnb.labels_).__name__, type(np.array([self.res5])).__name__) for group_fit, group_true in zip(jnb.groups_, self.res6): self.assertEqual((group_fit == group_true).all(), True) def test_predict_single_value(self): """ JenksNaturalBreaks.predict computes the class of a new data point """ jnb = JenksNaturalBreaks(n_classes=4) with self.assertRaises(AttributeError): jnb.predict(150) # predict single value jnb.fit(self.data2) self.assertEqual(jnb.predict(150), 0) def test_predict_multiple_values(self): """ JenksNaturalBreaks.predict computes the class of an array of values """ # predict before fit (not allowed) jnb = JenksNaturalBreaks(n_classes=4) with self.assertRaises(AttributeError): jnb.predict(150) jnb.fit(self.data2) # predict iterable return numpy array predicted = jnb.predict([150, 700]) for val_predict, val_true in zip(predicted, self.res7): self.assertEqual(val_predict, val_true) self.assertEqual(type(val_predict).__name__, type(val_true).__name__) # also works with other iterable as argument predicted = jnb.predict((i for i in range(150, 701, 550))) for val_predict, val_true in zip(predicted, self.res7): self.assertEqual(val_predict, val_true) self.assertEqual(type(val_predict).__name__, type(val_true).__name__) def test_grouping(self): """ JenksNaturalBreaks.groups groups new values according to the existing breaks """ # grouping before fit (not allowed) jnb = JenksNaturalBreaks(n_classes=4) with self.assertRaises(AttributeError): jnb.group(150) # grouping single value, list, numpy array jnb.fit(self.data2) for group_fit, group_true in zip(jnb.group(150), self.res8): self.assertEqual((group_fit == group_true).all(), True) for group_fit, group_true in zip(jnb.group([150, 700]), self.res9): self.assertEqual((group_fit == group_true).all(), True) for group_fit, group_true in zip(jnb.group(np.array([150, 700])), self.res9): self.assertEqual((group_fit == group_true).all(), True) def test_one_class(self): """ JenksNaturalBreaks should also work if only one classe is asked. """ jnb = JenksNaturalBreaks(n_classes=1) jnb.fit(self.data2) g = jnb.group(1000.) self.assertEqual(g, [np.array(1000.)]) l = jnb.get_label_(1000.) self.assertEqual(l, 0) def test_zero_class(self): """ JenksNaturalBreaks shouldn't work with less than 1 class. """ with self.assertRaises(ValueError): jnb = JenksNaturalBreaks(0) with self.assertRaises(ValueError): jnb = JenksNaturalBreaks(-12) with self.assertRaises(TypeError): jnb = JenksNaturalBreaks("abc") if __name__ == "__main__": unittest.main()