{ "info": { "author": "Kevin Arvai", "author_email": "arvkevi@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering :: Information Analysis" ], "description": "# kneed\n Knee-point detection in Python\n\n[![Downloads](https://pepy.tech/badge/kneed)](https://pepy.tech/project/kneed) [![Downloads](https://pepy.tech/badge/kneed/week)](https://pepy.tech/project/kneed) ![Dependents](https://badgen.net/github/dependents-repo/arvkevi/kneed/?icon=github) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/arvkevi/kneed/master) [![Build Status](https://travis-ci.com/arvkevi/kneed.svg?branch=master)](https://travis-ci.com/arvkevi/kneed) [![CodeFactor](https://www.codefactor.io/repository/github/arvkevi/kneed/badge)](https://www.codefactor.io/repository/github/arvkevi/kneed)\n\nThis repository is an attempt to implement the kneedle algorithm, published [here](https://www1.icsi.berkeley.edu/~barath/papers/kneedle-simplex11.pdf). Given a set of `x` and `y` values, `kneed` will return the knee point of the function. The knee point is the point of maximum curvature.\n\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/functions_args_summary.png)\n\n## Table of contents\n- [Installation](#installation)\n- [Usage](#usage)\n * [Input Data](#input-data)\n * [Find Knee](#find-knee)\n * [Visualize](#visualize)\n- [Examples](#examples)\n * [Sensitivity parameter (S)](#sensitivity-parameter-s)\n * [Online vs Offline detection](#online-vs-offline-detection)\n * [Polynomial Fit](#polynomial-fit)\n * [Noisy Gaussian](#noisygaussian)\n * [Select k clusters](#select-k-clusters)\n- [Contributing](#contributing)\n- [Citation](#citation)\n\n## Installation \n> Tested with Python 3.5, 3.6, and 3.7\n\n**anaconda**\n```bash\n$ conda install -c conda-forge kneed\n```\n\n**pip**\n```bash\n$ pip install kneed\n```\n\n**Clone from GitHub**\n```bash\n$ git clone https://github.com/arvkevi/kneed.git\n$ python setup.py install\n```\n\n## Usage\nThese steps introduce how to use `kneed` by reproducing Figure 2 from the manuscript.\n\n### Input Data\nThe `DataGenerator` class is only included as a utility to generate sample datasets. \n> Note: `x` and `y` must be equal length arrays.\n```python\nfrom kneed import DataGenerator, KneeLocator\n\nx, y = DataGenerator.figure2()\n\nprint([round(i, 3) for i in x])\nprint([round(i, 3) for i in y])\n\n[0.0, 0.111, 0.222, 0.333, 0.444, 0.556, 0.667, 0.778, 0.889, 1.0]\n[-5.0, 0.263, 1.897, 2.692, 3.163, 3.475, 3.696, 3.861, 3.989, 4.091]\n```\n\n### Find Knee \nThe knee (or elbow) point is calculated simply by instantiating the `KneeLocator` class with `x`, `y` and the appropriate `curve` and `direction`. \nHere, `kneedle.knee` and/or `kneedle.elbow` store the point of maximum curvature.\n\n```python\nkneedle = KneeLocator(x, y, S=1.0, curve='concave', direction='increasing')\n\nprint(round(kneedle.knee, 3))\n0.222\n\nprint(round(kneedle.elbow, 3))\n0.222\n```\n\n### Visualize\nThe `KneeLocator` class also has two plotting functions for quick visualizations.\n**Note that all (x, y) are transformed for the normalized plots**\n```python\n# Normalized data, normalized knee, and normalized distance curve.\nkneedle.plot_knee_normalized()\n```\n\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/figure2.knee.png)\n\n```python\n# Raw data and knee.\nkneedle.plot_knee()\n```\n\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/figure2.knee.raw.png)\n\n## Examples\n### Sensitivity Parameter (S)\nThe knee point selected is tunable by setting the sensitivity parameter **S**. \nFrom the manuscript:\n> The sensitivity parameter allows us to adjust how aggressive we want Kneedle\nto be when detecting knees. Smaller values for S detect\nknees quicker, while larger values are more conservative.\nPut simply, S is a measure of how many \u201cflat\u201d points we\nexpect to see in the unmodified data curve before declaring\na knee.\n\n```python\nimport numpy as np\nnp.random.seed(23)\n\nsensitivity = [1, 3, 5, 10, 100, 200, 400]\nknees = []\nnorm_knees = []\n\nn = 1000\nx = range(1, n + 1)\ny = sorted(np.random.gamma(0.5, 1.0, n), reverse=True)\nfor s in sensitivity:\n kl = KneeLocator(x, y, curve='convex', direction='decreasing', S=s)\n knees.append(kl.knee)\n norm_knees.append(kl.norm_knee)\n\nprint(knees)\n[43, 137, 178, 258, 305, 482, 482]\n\nprint([nk.round(2) for nk in norm_knees])\n[0.04, 0.14, 0.18, 0.26, 0.3, 0.48, 0.48]\n\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot');\nplt.figure(figsize=(8, 6));\nplt.plot(kl.x_normalized, kl.y_normalized);\nplt.plot(kl.x_distance, kl.y_distance);\ncolors = ['r', 'g', 'k', 'm', 'c', 'orange']\nfor k, c, s in zip(norm_knees, colors, sensitivity):\n plt.vlines(k, 0, 1, linestyles='--', colors=c, label=f'S = {s}');\nplt.legend();\n```\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/S_parameter.png)\n\nNotice that any **S**>200 will result in a knee at 482 (0.48, normalized) in the plot above.\n\n### Online vs Offline Detection\nThe knee point can be corrected if the parameter `online` is `True` (default). This mode will step through each element in \n`x`. In contrast, if `online` is `False`, kneed will run in offline mode and return the first knee point identified.\n\nUsing the `x` and `y` from the Sensitivity example above, this time, let's keep `S=1` but modify `online`.\n```python\nkl_online = KneeLocator(x, y, curve='convex', direction='decreasing', online=True)\nkl_offline = KneeLocator(x, y, curve='convex', direction='decreasing', online=False)\n\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot');\nplt.figure(figsize=(8, 6));\nplt.plot(kl_online.x_normalized, kl_online.y_normalized);\nplt.plot(kl_online.x_distance, kl_online.y_distance);\ncolors = ['r', 'g']\nfor k, c, o in zip([kl_online.norm_knee, kl_offline.norm_knee], ['r', 'g'], ['online', 'offline']):\n plt.vlines(k, 0, 1, linestyles='--', colors=c, label=o);\nplt.legend();\n```\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/online_vs_offline.png)\n\n### Polynomial Fit\nHere is an example of a \"bumpy\" or \"noisy\" line where the default `scipy.interpolate.interp1d` spline fitting method does not provide the best estimate for the point of maximum curvature.\nThis example demonstrates that setting the parameter `interp_method='polynomial'` will choose a more accurate point by smoothing the line.\n> The argument for `interp_method` parameter is a string of either \"interp1d\" or \"polynomial\".\n```python\nx = list(range(90))\ny = [\n 7304, 6978, 6666, 6463, 6326, 6048, 6032, 5762, 5742,\n 5398, 5256, 5226, 5001, 4941, 4854, 4734, 4558, 4491,\n 4411, 4333, 4234, 4139, 4056, 4022, 3867, 3808, 3745,\n 3692, 3645, 3618, 3574, 3504, 3452, 3401, 3382, 3340,\n 3301, 3247, 3190, 3179, 3154, 3089, 3045, 2988, 2993,\n 2941, 2875, 2866, 2834, 2785, 2759, 2763, 2720, 2660,\n 2690, 2635, 2632, 2574, 2555, 2545, 2513, 2491, 2496,\n 2466, 2442, 2420, 2381, 2388, 2340, 2335, 2318, 2319,\n 2308, 2262, 2235, 2259, 2221, 2202, 2184, 2170, 2160,\n 2127, 2134, 2101, 2101, 2066, 2074, 2063, 2048, 2031\n]\n\n# the default spline fit, `interp_method='interp1d'`\nkneedle = KneeLocator(x, y, S=1.0, curve='convex', direction='decreasing', interp_method='interp1d')\nkneedle.plot_knee_normalized()\n```\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/bumpy_line.png)\n\n```python\n# The same data, only using a polynomial fit this time.\nkneedle = KneeLocator(x, y, S=1.0, curve='convex', direction='decreasing', interp_method='polynomial')\nkneedle.plot_knee_normalized()\n```\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/bumpy_line.smoothed.png)\n\n### NoisyGaussian\nFigure 3 from the manuscript estimates the knee to be `x=60` for a `NoisyGaussian`.\nThis simulate 5,000 `NoisyGaussian` instances and finds the average.\n```python\nknees = []\nfor i in range(5):\n x, y = DataGenerator.noisy_gaussian(mu=50, sigma=10, N=1000)\n kneedle = KneeLocator(x, y, curve='concave', direction='increasing', interp_method='polynomial')\n knees.append(kneedle.knee)\n\n# average knee point\nround(sum(knees) / len(knees), 3)\n60.921\n```\n\n### Select k clusters\n\nFind the optimal number of clusters (k) to use in k-means clustering.\nSee the [tutorial in the notebooks](https://github.com/arvkevi/kneed/blob/master/notebooks/decreasing_function_walkthrough.ipynb) directory.\n\n```python\nKneeLocator(x, y, curve='convex', direction='decreasing')\n```\n\n![](https://raw.githubusercontent.com/arvkevi/kneed/master/images/knee.png)\n\n## Contributing\n\nContributions are welcome, please refer to [CONTRIBUTING](https://github.com/arvkevi/kneed/blob/master/CONTRIBUTING.md) \nto learn more about how to contribute. \n\n## Citation\n\nFinding a \u201cKneedle\u201d in a Haystack:\nDetecting Knee Points in System Behavior\nVille Satopa\n\u2020\n, Jeannie Albrecht\u2020\n, David Irwin\u2021\n, and Barath Raghavan\u00a7\n\u2020Williams College, Williamstown, MA\n\u2021University of Massachusetts Amherst, Amherst, MA\n\u00a7\nInternational Computer Science Institute, Berkeley, CA\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/arvkevi/kneed/tarball/0.5.0", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/arvkevi/kneed", "keywords": "knee-detection system", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "kneed", "package_url": "https://pypi.org/project/kneed/", "platform": "", "project_url": "https://pypi.org/project/kneed/", "project_urls": { "Download": "https://github.com/arvkevi/kneed/tarball/0.5.0", "Homepage": "https://github.com/arvkevi/kneed" }, "release_url": "https://pypi.org/project/kneed/0.5.0/", "requires_dist": [ "matplotlib", "numpy (>=1.14.2)", "scikit-learn", "scipy" ], "requires_python": "", "summary": "Knee-point detection in Python", "version": "0.5.0" }, "last_serial": 5915422, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "620825b5158b05e3e00b7c45e0c3c6dd", "sha256": "fbb0c7d6d3f1dcabec4a56a1c8831b0c1678d5cedbb9602d830a446c48adce06" }, "downloads": -1, "filename": "kneed-0.0.1.tar.gz", "has_sig": false, "md5_digest": "620825b5158b05e3e00b7c45e0c3c6dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4475, "upload_time": "2017-12-11T02:27:45", "url": "https://files.pythonhosted.org/packages/f6/77/26ba65e6678958d4857c31f1f856ad482e486fcccc31e7654348315b4317/kneed-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "44e9bf2a96651d53f99b27b781ae8dc9", "sha256": "fd610b2e76ceee71ca852bc1f6db989eefd399fbf7b21b7fb950f54b5d08761b" }, "downloads": -1, "filename": "kneed-0.0.2.tar.gz", "has_sig": false, "md5_digest": "44e9bf2a96651d53f99b27b781ae8dc9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4488, "upload_time": "2017-12-11T02:38:46", "url": "https://files.pythonhosted.org/packages/2a/b6/aed3a46951fa44bbd119cdac9176ab49ef67f39d70a23209928c2d45a8a3/kneed-0.0.2.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "8e032400e69e37db1ecdad1e094041c4", "sha256": "35c1f7f51daa0f449040d91d183e2f67aabc0afbd136cf338abc185359d98036" }, "downloads": -1, "filename": "kneed-0.0.4.tar.gz", "has_sig": false, "md5_digest": "8e032400e69e37db1ecdad1e094041c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4969, "upload_time": "2018-02-28T02:18:03", "url": "https://files.pythonhosted.org/packages/9d/88/d7079f07a13e6df42a4a08a100e236a25113aa9575263cc91b58c1b769c1/kneed-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "9a86cfbd117a871e6efda2752af00892", "sha256": "610f965c71072fbe029e384c7029a2feacf67aa64d6c7958d961931f5563e1b1" }, "downloads": -1, "filename": "kneed-0.0.5.tar.gz", "has_sig": false, "md5_digest": "9a86cfbd117a871e6efda2752af00892", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5026, "upload_time": "2018-07-06T00:37:53", "url": "https://files.pythonhosted.org/packages/5f/5f/02e15e50b34599fe35c27d382bdbeef873586fa453546b6d475c37a7069d/kneed-0.0.5.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "fe4e09f7b6ec3d89a55ca413f3782940", "sha256": "3d4dfe6d9a48f3806840193c2fe1fe9cf9d55cb144c68494f4cc7da11713d72d" }, "downloads": -1, "filename": "kneed-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fe4e09f7b6ec3d89a55ca413f3782940", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6207, "upload_time": "2018-10-08T04:33:02", "url": "https://files.pythonhosted.org/packages/0a/18/7f4d247ed8822d542bc8deb08898686c7972020ad9f1dbead0c48f14b789/kneed-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "da05924feae567f35ce63eee06295a96", "sha256": "9049fa23f96ca91d5c65857461dab703adf12b9773e337ae2274ed5f8e35fbc5" }, "downloads": -1, "filename": "kneed-0.1.0.tar.gz", "has_sig": false, "md5_digest": "da05924feae567f35ce63eee06295a96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5172, "upload_time": "2018-10-08T04:33:03", "url": "https://files.pythonhosted.org/packages/29/cc/d9a82da82bf2ab43257e542072a64794de4b681e48e6b79e145448681815/kneed-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "5b0a581be9c2cb2bc40c22839bce08e9", "sha256": "e0c690a26b31ebb1f8251a121348248ffbf10b9b794be0de076585bb8ef25772" }, "downloads": -1, "filename": "kneed-0.1.1.tar.gz", "has_sig": false, "md5_digest": "5b0a581be9c2cb2bc40c22839bce08e9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5061, "upload_time": "2018-11-22T02:32:49", "url": "https://files.pythonhosted.org/packages/3d/84/964d5a0622752009de6e3ca4918d4f992ac26395d4fa897c243078f8e813/kneed-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "b7b733389d41ff87a990419ae8aaeaa2", "sha256": "1930ec453d5b12dc8674b671f86a0ae506c2a4defb7ace5a7fb944f799679098" }, "downloads": -1, "filename": "kneed-0.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b7b733389d41ff87a990419ae8aaeaa2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6812, "upload_time": "2019-01-14T18:51:04", "url": "https://files.pythonhosted.org/packages/5a/c0/bc48fa9169761f2a6787963bd44641ced4309a82806297f5b3a6ba1b4adf/kneed-0.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f4e4d001e7cf7c94fcae49cd69b38d99", "sha256": "aa0f2ce3393be485171311acf85fbee1654a8fe0351b84295a82a0155cf3a177" }, "downloads": -1, "filename": "kneed-0.2.0.tar.gz", "has_sig": false, "md5_digest": "f4e4d001e7cf7c94fcae49cd69b38d99", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5699, "upload_time": "2019-01-14T18:51:06", "url": "https://files.pythonhosted.org/packages/43/9f/a4a98703a8fd162f8241c6b76a59fb02abe2d0280cd26e38cace18d9263d/kneed-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "76b7a7b615ca96fecc97e92eb27e0101", "sha256": "6640c0db473486b233bf40b9f422606d65ab6e691d74a10450a4ec6d1345f1a0" }, "downloads": -1, "filename": "kneed-0.2.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "76b7a7b615ca96fecc97e92eb27e0101", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6835, "upload_time": "2019-01-14T19:07:23", "url": "https://files.pythonhosted.org/packages/73/eb/88e2300766252fcee6bf288b40bdec6d433a82115617bbad402ee55003d0/kneed-0.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ca0785119052d12c737acf2b9664dc59", "sha256": "ad25dbae9fdc0c9e8b126515b21cf9061d8d84ea28adce1956cf54f66400ffd1" }, "downloads": -1, "filename": "kneed-0.2.1.tar.gz", "has_sig": false, "md5_digest": "ca0785119052d12c737acf2b9664dc59", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5733, "upload_time": "2019-01-14T19:07:24", "url": "https://files.pythonhosted.org/packages/db/fd/32f59c5c5a2e82fddcbe31c7404827f6e42c56cd4dde96084cc2cd984bc5/kneed-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "358dc117b6532ecd3615b0af4ea613e2", "sha256": "c9edea7b5735baf3e777da99cea776d7aafedd6e473fa6f0db805a3655c79b37" }, "downloads": -1, "filename": "kneed-0.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "358dc117b6532ecd3615b0af4ea613e2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6762, "upload_time": "2019-01-14T22:06:40", "url": "https://files.pythonhosted.org/packages/8e/e1/7113051b01f12949f4ece925289e37656f0045b6ce665e6ecffeb60f3125/kneed-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3fb9daac597e11973b0f07f7af1d473b", "sha256": "d490adf50ace7afce0e28893cc3a30a4aecd91153eb8c285e5df6e70e75482b6" }, "downloads": -1, "filename": "kneed-0.2.2.tar.gz", "has_sig": false, "md5_digest": "3fb9daac597e11973b0f07f7af1d473b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5649, "upload_time": "2019-01-14T22:06:42", "url": "https://files.pythonhosted.org/packages/cc/11/965b78b3d07d6cff3c3f7ac4f74388583139ffc757ec26d535ea79392c80/kneed-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "5de3483e4753d2dcafc0448d124dd956", "sha256": "937c25e712e89637f7d267bfc24450ea48e816c3edb68bea164e460db4fcb298" }, "downloads": -1, "filename": "kneed-0.2.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5de3483e4753d2dcafc0448d124dd956", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6760, "upload_time": "2019-01-15T01:39:14", "url": "https://files.pythonhosted.org/packages/4b/5f/1a22d47543cec7f64b7e84cfeb04074d8ad8249b3fdca5d5af39e870500a/kneed-0.2.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "324aaa63db11421e1d470c05a69a2749", "sha256": "39389c49b0cd9d976a3aaa8400aa9313bfb580818bc1ef60e0fcf4c9bb4f871e" }, "downloads": -1, "filename": "kneed-0.2.3.tar.gz", "has_sig": false, "md5_digest": "324aaa63db11421e1d470c05a69a2749", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6152, "upload_time": "2019-01-15T01:39:16", "url": "https://files.pythonhosted.org/packages/42/86/cf0a1fc99c84c0cecf397b643e1cee9be457c55ee42296f27f0f8b8b9af3/kneed-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "a0dde6666f8a3cb2c8f2f1336c1d67ef", "sha256": "c28ab582b1756de28f6d4351d3c4b32fc60190d6be9148ee63a318719059f0ef" }, "downloads": -1, "filename": "kneed-0.2.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a0dde6666f8a3cb2c8f2f1336c1d67ef", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6762, "upload_time": "2019-01-19T12:40:37", "url": "https://files.pythonhosted.org/packages/63/54/ec809d2193800b4560f3828cc0e5950f68e5972519607f5f0b4bba82245f/kneed-0.2.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f0e81ebf5af5959dd9aa0c9af840aa87", "sha256": "7b16643a339a5301942ca69fa0890d3bf86d610bce9fb39db4763fec9730d0d8" }, "downloads": -1, "filename": "kneed-0.2.4.tar.gz", "has_sig": false, "md5_digest": "f0e81ebf5af5959dd9aa0c9af840aa87", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6973, "upload_time": "2019-01-19T12:40:38", "url": "https://files.pythonhosted.org/packages/be/39/41f391f3887eb413afecac80cc0b80d32c89378759cceb8de4218fa77423/kneed-0.2.4.tar.gz" } ], "0.3.0": [], "0.3.1": [ { "comment_text": "", "digests": { "md5": "d1aaa2a6f05a42baef040ee5766b305e", "sha256": "0e6d38e218864f802de9377a688555ba42d2064666b432dba69fd5e38cb6d047" }, "downloads": -1, "filename": "kneed-0.3.1.tar.gz", "has_sig": false, "md5_digest": "d1aaa2a6f05a42baef040ee5766b305e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9148, "upload_time": "2019-04-16T02:15:19", "url": "https://files.pythonhosted.org/packages/3a/b8/07cd840dd535b8c21ce5c58e9cc36ea47086a9dc3ce2db93cdbdb972cea9/kneed-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "fe8e35e43b5486ab69cbb3c3d43d475a", "sha256": "6aea8c495aab16b529c8b46caea83bd074d57a1f0cc5bc5ab551f8a2d53db23e" }, "downloads": -1, "filename": "kneed-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fe8e35e43b5486ab69cbb3c3d43d475a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8708, "upload_time": "2019-07-06T10:58:55", "url": "https://files.pythonhosted.org/packages/c5/8b/d4125a10afe735f8c50c77bf525ee67bd697811a54f6d894a3d914a4c121/kneed-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2b7d65d1998509e43896933cf9aa47bd", "sha256": "40af95e58bbca3f7897c1a121e5442629e848af23e57cd922ae8a1681d7f9821" }, "downloads": -1, "filename": "kneed-0.4.0.tar.gz", "has_sig": false, "md5_digest": "2b7d65d1998509e43896933cf9aa47bd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13066, "upload_time": "2019-07-06T10:58:57", "url": "https://files.pythonhosted.org/packages/f3/23/0fcd1e2fa02e9f4f346669eb45e60240dcf3b52c0a3ad26f4b4ad1f538a6/kneed-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "05365661e3f1385f5a432c45aeea23c8", "sha256": "8a3e6a78f9036e08d2f61b17b020a1035f19c28b6d0793d96c031396f959ba95" }, "downloads": -1, "filename": "kneed-0.4.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "05365661e3f1385f5a432c45aeea23c8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8830, "upload_time": "2019-07-06T14:11:07", "url": "https://files.pythonhosted.org/packages/ab/c5/02a3fdcc6c7f6d1ac0b2537f6c61bc9975db718193b97fb4f42c768d0020/kneed-0.4.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5f8cd723780999ba4794a39e005e3ddc", "sha256": "cccf34f9a1427c3cce8efbad5d34b10606aadef007607a292c4789d582f66bdd" }, "downloads": -1, "filename": "kneed-0.4.1.tar.gz", "has_sig": false, "md5_digest": "5f8cd723780999ba4794a39e005e3ddc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13129, "upload_time": "2019-07-06T14:11:09", "url": "https://files.pythonhosted.org/packages/25/77/252f588691b421c6b4cd440cce2f4628102e3eb5b22eed2681a61aa0ce1b/kneed-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "5c0e72c760d320bc8febcb850f441ede", "sha256": "b9efeebd3816ce951ef148fec8a3bd8aa267334aba49f410a7db9031cac4fd46" }, "downloads": -1, "filename": "kneed-0.4.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5c0e72c760d320bc8febcb850f441ede", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9527, "upload_time": "2019-09-15T18:27:29", "url": "https://files.pythonhosted.org/packages/b0/b2/c591ddd71eecc714de0965f281d911a5f46ca06f8aa3bcc734f627cbc70c/kneed-0.4.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c992df165e3e0db1625f4424819b683f", "sha256": "0a3adc7f17bf19904f0e2f1d7f8ad61480c3ba80206479c382b8d633544da82a" }, "downloads": -1, "filename": "kneed-0.4.2.tar.gz", "has_sig": false, "md5_digest": "c992df165e3e0db1625f4424819b683f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13469, "upload_time": "2019-09-15T18:27:31", "url": "https://files.pythonhosted.org/packages/c2/19/6e4c1630bc45399e6a78e2bcf4a0eee76e193cebd720d2639bc9408036c2/kneed-0.4.2.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "d5cd6c315adc9a9f20cf14b69a7eaa1c", "sha256": "8a7d59289b234f14de9e958d4330944a7422545ed048ca3ef559f4c8245548e0" }, "downloads": -1, "filename": "kneed-0.5.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d5cd6c315adc9a9f20cf14b69a7eaa1c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9917, "upload_time": "2019-10-01T23:47:21", "url": "https://files.pythonhosted.org/packages/d1/c3/067cce73eafcba9828849d5f141ab9742734432d6dae59dc3353416cea04/kneed-0.5.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "42b5901699ac0bb0f6b15015578b4bab", "sha256": "8634f0270a6b7646f6446867f5dcc49655736f0e0c2a9a8c0694558304571855" }, "downloads": -1, "filename": "kneed-0.5.0.tar.gz", "has_sig": false, "md5_digest": "42b5901699ac0bb0f6b15015578b4bab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14355, "upload_time": "2019-10-01T23:47:22", "url": "https://files.pythonhosted.org/packages/95/9f/e52c702e020a98814d94c91e64abbb907e7e5be78602f599aefb48e2159a/kneed-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d5cd6c315adc9a9f20cf14b69a7eaa1c", "sha256": "8a7d59289b234f14de9e958d4330944a7422545ed048ca3ef559f4c8245548e0" }, "downloads": -1, "filename": "kneed-0.5.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d5cd6c315adc9a9f20cf14b69a7eaa1c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9917, "upload_time": "2019-10-01T23:47:21", "url": "https://files.pythonhosted.org/packages/d1/c3/067cce73eafcba9828849d5f141ab9742734432d6dae59dc3353416cea04/kneed-0.5.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "42b5901699ac0bb0f6b15015578b4bab", "sha256": "8634f0270a6b7646f6446867f5dcc49655736f0e0c2a9a8c0694558304571855" }, "downloads": -1, "filename": "kneed-0.5.0.tar.gz", "has_sig": false, "md5_digest": "42b5901699ac0bb0f6b15015578b4bab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14355, "upload_time": "2019-10-01T23:47:22", "url": "https://files.pythonhosted.org/packages/95/9f/e52c702e020a98814d94c91e64abbb907e7e5be78602f599aefb48e2159a/kneed-0.5.0.tar.gz" } ] }