{ "info": { "author": "Ashim Bhattarai", "author_email": "", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "## missingpy\n\n`missingpy` is a library for missing data imputation in Python. It has an \nAPI consistent with [scikit-learn](http://scikit-learn.org/stable/), so users \nalready comfortable with that interface will find themselves in familiar \nterrain. Currently, the library supports k-Nearest Neighbors based \nimputation and Random Forest based imputation (MissForest) but we plan to add \nother imputation tools in the future so please stay tuned!\n\n## Installation\n\n`pip install missingpy`\n\n## k-Nearest Neighbors (kNN) Imputation\n\n### Example\n```\n# Let X be an array containing missing values\nfrom missingpy import KNNImputer\nimputer = KNNImputer()\nX_imputed = imputer.fit_transform(X)\n```\n\n### Description\nThe `KNNImputer` class provides imputation for completing missing\nvalues using the k-Nearest Neighbors approach. Each sample's missing values\nare imputed using values from `n_neighbors` nearest neighbors found in the\ntraining set. Note that if a sample has more than one feature missing, then\nthe sample can potentially have multiple sets of `n_neighbors`\ndonors depending on the particular feature being imputed.\n\nEach missing feature is then imputed as the average, either weighted or\nunweighted, of these neighbors. Where the number of donor neighbors is less\nthan `n_neighbors`, the training set average for that feature is used\nfor imputation. The total number of samples in the training set is, of course,\nalways greater than or equal to the number of nearest neighbors available for\nimputation, depending on both the overall sample size as well as the number of\nsamples excluded from nearest neighbor calculation because of too many missing\nfeatures (as controlled by `row_max_missing`).\nFor more information on the methodology, see [1].\n\nThe following snippet demonstrates how to replace missing values,\nencoded as `np.nan`, using the mean feature value of the two nearest\nneighbors of the rows that contain the missing values::\n\n >>> import numpy as np\n >>> from missingpy import KNNImputer\n >>> nan = np.nan\n >>> X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]\n >>> imputer = KNNImputer(n_neighbors=2, weights=\"uniform\")\n >>> imputer.fit_transform(X)\n array([[1. , 2. , 4. ],\n [3. , 4. , 3. ],\n [5.5, 6. , 5. ],\n [8. , 8. , 7. ]])\n\n### API\n KNNImputer(missing_values=\"NaN\", n_neighbors=5, weights=\"uniform\", \n metric=\"masked_euclidean\", row_max_missing=0.5, \n col_max_missing=0.8, copy=True)\n\n Parameters\n ----------\n missing_values : integer or \"NaN\", optional (default = \"NaN\")\n The placeholder for the missing values. All occurrences of\n `missing_values` will be imputed. For missing values encoded as\n ``np.nan``, use the string value \"NaN\".\n\n n_neighbors : int, optional (default = 5)\n Number of neighboring samples to use for imputation.\n\n weights : str or callable, optional (default = \"uniform\")\n Weight function used in prediction. Possible values:\n\n - 'uniform' : uniform weights. All points in each neighborhood\n are weighted equally.\n - 'distance' : weight points by the inverse of their distance.\n in this case, closer neighbors of a query point will have a\n greater influence than neighbors which are further away.\n - [callable] : a user-defined function which accepts an\n array of distances, and returns an array of the same shape\n containing the weights.\n\n metric : str or callable, optional (default = \"masked_euclidean\")\n Distance metric for searching neighbors. Possible values:\n - 'masked_euclidean'\n - [callable] : a user-defined function which conforms to the\n definition of _pairwise_callable(X, Y, metric, **kwds). In other\n words, the function accepts two arrays, X and Y, and a\n ``missing_values`` keyword in **kwds and returns a scalar distance\n value.\n\n row_max_missing : float, optional (default = 0.5)\n The maximum fraction of columns (i.e. features) that can be missing\n before the sample is excluded from nearest neighbor imputation. It\n means that such rows will not be considered a potential donor in\n ``fit()``, and in ``transform()`` their missing feature values will be\n imputed to be the column mean for the entire dataset.\n\n col_max_missing : float, optional (default = 0.8)\n The maximum fraction of rows (or samples) that can be missing\n for any feature beyond which an error is raised.\n\n copy : boolean, optional (default = True)\n If True, a copy of X will be created. If False, imputation will\n be done in-place whenever possible. Note that, if metric is\n \"masked_euclidean\" and copy=False then missing_values in the\n input matrix X will be overwritten with zeros.\n\n Attributes\n ----------\n statistics_ : 1-D array of length {n_features}\n The 1-D array contains the mean of each feature calculated using\n observed (i.e. non-missing) values. This is used for imputing\n missing values in samples that are either excluded from nearest\n neighbors search because they have too many ( > row_max_missing)\n missing features or because all of the sample's k-nearest neighbors\n (i.e., the potential donors) also have the relevant feature value\n missing.\n\n Methods\n -------\n fit(X, y=None):\n Fit the imputer on X.\n\n Parameters\n ----------\n X : {array-like}, shape (n_samples, n_features)\n Input data, where ``n_samples`` is the number of samples and\n ``n_features`` is the number of features.\n\n Returns\n -------\n self : object\n Returns self.\n\n\n transform(X):\n Impute all missing values in X.\n\n Parameters\n ----------\n X : {array-like}, shape = [n_samples, n_features]\n The input data to complete.\n\n Returns\n -------\n X : {array-like}, shape = [n_samples, n_features]\n The imputed dataset.\n\n\n fit_transform(X, y=None, **fit_params):\n Fit KNNImputer and impute all missing values in X.\n\n Parameters\n ----------\n X : {array-like}, shape (n_samples, n_features)\n Input data, where ``n_samples`` is the number of samples and\n ``n_features`` is the number of features.\n\n Returns\n -------\n X : {array-like}, shape (n_samples, n_features)\n Returns imputed dataset. \n\n### References\n1. Olga Troyanskaya, Michael Cantor, Gavin Sherlock, Pat Brown, Trevor\n Hastie, Robert Tibshirani, David Botstein and Russ B. Altman, Missing value\n estimation methods for DNA microarrays, BIOINFORMATICS Vol. 17 no. 6, 2001\n Pages 520-525.\n\n## Random Forest Imputation (MissForest)\n\n### Example\n```\n# Let X be an array containing missing values\nfrom missingpy import MissForest\nimputer = MissForest()\nX_imputed = imputer.fit_transform(X)\n```\n\n### Description\nMissForest imputes missing values using Random Forests in an iterative\nfashion [1]. By default, the imputer begins imputing missing values of the\ncolumn (which is expected to be a variable) with the smallest number of\nmissing values -- let's call this the candidate column.\nThe first step involves filling any missing values of the remaining,\nnon-candidate, columns with an initial guess, which is the column mean for\ncolumns representing numerical variables and the column mode for columns\nrepresenting categorical variables. Note that the categorical variables \nneed to be explicitly identified during the imputer's `fit()` method call \n(see API for more information). After that, the imputer fits a random\nforest model with the candidate column as the outcome variable and the\nremaining columns as the predictors over all rows where the candidate\ncolumn values are not missing.\nAfter the fit, the missing rows of the candidate column are\nimputed using the prediction from the fitted Random Forest. The\nrows of the non-candidate columns act as the input data for the fitted\nmodel.\nFollowing this, the imputer moves on to the next candidate column with the\nsecond smallest number of missing values from among the non-candidate\ncolumns in the first round. The process repeats itself for each column\nwith a missing value, possibly over multiple iterations or epochs for\neach column, until the stopping criterion is met.\nThe stopping criterion is governed by the \"difference\" between the imputed\narrays over successive iterations. For numerical variables (`num_vars_`),\nthe difference is defined as follows:\n\n sum((X_new[:, num_vars_] - X_old[:, num_vars_]) ** 2) /\n sum((X_new[:, num_vars_]) ** 2)\n\nFor categorical variables(`cat_vars_`), the difference is defined as follows:\n\n sum(X_new[:, cat_vars_] != X_old[:, cat_vars_])) / n_cat_missing\n\nwhere `X_new` is the newly imputed array, `X_old` is the array imputed in the\nprevious round, `n_cat_missing` is the total number of categorical\nvalues that are missing, and the `sum()` is performed both across rows\nand columns. Following [1], the stopping criterion is considered to have\nbeen met when difference between `X_new` and `X_old` increases for the first\ntime for both types of variables (if available).\n\n\n >>> from missingpy import MissForest\n >>> nan = float(\"NaN\")\n >>> X = [[1, 2, nan], [3, 4, 3], [nan, 6, 5], [8, 8, 7]]\n >>> imputer = MissForest()\n >>> imputer.fit_transform(X)\n Iteration: 0\n Iteration: 1\n Iteration: 2\n Iteration: 3\n array([[1. , 2. , 4. ],\n [3. , 4. , 3. ],\n [3.16, 6. , 5. ],\n [8. , 8. , 7. ]])\n\n### API\n MissForest(max_iter=10, decreasing=False, missing_values=np.nan,\n copy=True, n_estimators=100, criterion=('mse', 'gini'),\n max_depth=None, min_samples_split=2, min_samples_leaf=1,\n min_weight_fraction_leaf=0.0, max_features='auto',\n max_leaf_nodes=None, min_impurity_decrease=0.0,\n bootstrap=True, oob_score=False, n_jobs=-1, random_state=None,\n verbose=0, warm_start=False, class_weight=None)\n\n Parameters\n ----------\n NOTE: Most parameter definitions below are taken verbatim from the\n Scikit-Learn documentation at [2] and [3].\n\n max_iter : int, optional (default = 10)\n The maximum iterations of the imputation process. Each column with a\n missing value is imputed exactly once in a given iteration.\n\n decreasing : boolean, optional (default = False)\n If set to True, columns are sorted according to decreasing number of\n missing values. In other words, imputation will move from imputing\n columns with the largest number of missing values to columns with\n fewest number of missing values.\n\n missing_values : np.nan, integer, optional (default = np.nan)\n The placeholder for the missing values. All occurrences of\n `missing_values` will be imputed.\n\n copy : boolean, optional (default = True)\n If True, a copy of X will be created. If False, imputation will\n be done in-place whenever possible.\n\n criterion : tuple, optional (default = ('mse', 'gini'))\n The function to measure the quality of a split.The first element of\n the tuple is for the Random Forest Regressor (for imputing numerical\n variables) while the second element is for the Random Forest\n Classifier (for imputing categorical variables).\n\n n_estimators : integer, optional (default=100)\n The number of trees in the forest.\n\n max_depth : integer or None, optional (default=None)\n The maximum depth of the tree. If None, then nodes are expanded until\n all leaves are pure or until all leaves contain less than\n min_samples_split samples.\n\n min_samples_split : int, float, optional (default=2)\n The minimum number of samples required to split an internal node:\n - If int, then consider `min_samples_split` as the minimum number.\n - If float, then `min_samples_split` is a fraction and\n `ceil(min_samples_split * n_samples)` are the minimum\n number of samples for each split.\n\n min_samples_leaf : int, float, optional (default=1)\n The minimum number of samples required to be at a leaf node.\n A split point at any depth will only be considered if it leaves at\n least ``min_samples_leaf`` training samples in each of the left and\n right branches. This may have the effect of smoothing the model,\n especially in regression.\n - If int, then consider `min_samples_leaf` as the minimum number.\n - If float, then `min_samples_leaf` is a fraction and\n `ceil(min_samples_leaf * n_samples)` are the minimum\n number of samples for each node.\n\n min_weight_fraction_leaf : float, optional (default=0.)\n The minimum weighted fraction of the sum total of weights (of all\n the input samples) required to be at a leaf node. Samples have\n equal weight when sample_weight is not provided.\n\n max_features : int, float, string or None, optional (default=\"auto\")\n The number of features to consider when looking for the best split:\n - If int, then consider `max_features` features at each split.\n - If float, then `max_features` is a fraction and\n `int(max_features * n_features)` features are considered at each\n split.\n - If \"auto\", then `max_features=sqrt(n_features)`.\n - If \"sqrt\", then `max_features=sqrt(n_features)` (same as \"auto\").\n - If \"log2\", then `max_features=log2(n_features)`.\n - If None, then `max_features=n_features`.\n Note: the search for a split does not stop until at least one\n valid partition of the node samples is found, even if it requires to\n effectively inspect more than ``max_features`` features.\n\n max_leaf_nodes : int or None, optional (default=None)\n Grow trees with ``max_leaf_nodes`` in best-first fashion.\n Best nodes are defined as relative reduction in impurity.\n If None then unlimited number of leaf nodes.\n\n min_impurity_decrease : float, optional (default=0.)\n A node will be split if this split induces a decrease of the impurity\n greater than or equal to this value.\n The weighted impurity decrease equation is the following::\n N_t / N * (impurity - N_t_R / N_t * right_impurity\n - N_t_L / N_t * left_impurity)\n where ``N`` is the total number of samples, ``N_t`` is the number of\n samples at the current node, ``N_t_L`` is the number of samples in the\n left child, and ``N_t_R`` is the number of samples in the right child.\n ``N``, ``N_t``, ``N_t_R`` and ``N_t_L`` all refer to the weighted sum,\n if ``sample_weight`` is passed.\n\n bootstrap : boolean, optional (default=True)\n Whether bootstrap samples are used when building trees.\n\n oob_score : bool (default=False)\n Whether to use out-of-bag samples to estimate\n the generalization accuracy.\n\n n_jobs : int or None, optional (default=None)\n The number of jobs to run in parallel for both `fit` and `predict`.\n ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.\n ``-1`` means using all processors. See :term:`Glossary `\n for more details.\n\n random_state : int, RandomState instance or None, optional (default=None)\n If int, random_state is the seed used by the random number generator;\n If RandomState instance, random_state is the random number generator;\n If None, the random number generator is the RandomState instance used\n by `np.random`.\n\n verbose : int, optional (default=0)\n Controls the verbosity when fitting and predicting.\n\n warm_start : bool, optional (default=False)\n When set to ``True``, reuse the solution of the previous call to fit\n and add more estimators to the ensemble, otherwise, just fit a whole\n new forest. See :term:`the Glossary `.\n\n class_weight : dict, list of dicts, \"balanced\", \"balanced_subsample\" or \\\n None, optional (default=None)\n Weights associated with classes in the form ``{class_label: weight}``.\n If not given, all classes are supposed to have weight one. For\n multi-output problems, a list of dicts can be provided in the same\n order as the columns of y.\n Note that for multioutput (including multilabel) weights should be\n defined for each class of every column in its own dict. For example,\n for four-class multilabel classification weights should be\n [{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}] instead of\n [{1:1}, {2:5}, {3:1}, {4:1}].\n The \"balanced\" mode uses the values of y to automatically adjust\n weights inversely proportional to class frequencies in the input data\n as ``n_samples / (n_classes * np.bincount(y))``\n The \"balanced_subsample\" mode is the same as \"balanced\" except that\n weights are computed based on the bootstrap sample for every tree\n grown.\n For multi-output, the weights of each column of y will be multiplied.\n Note that these weights will be multiplied with sample_weight (passed\n through the fit method) if sample_weight is specified.\n NOTE: This parameter is only applicable for Random Forest Classifier\n objects (i.e., for categorical variables).\n\n Attributes\n ----------\n statistics_ : Dictionary of length two\n The first element is an array with the mean of each numerical feature\n being imputed while the second element is an array of modes of\n categorical features being imputed (if available, otherwise it\n will be None).\n\n Methods\n -------\n fit(self, X, y=None, cat_vars=None):\n Fit the imputer on X.\n\n Parameters\n ----------\n X : {array-like}, shape (n_samples, n_features)\n Input data, where ``n_samples`` is the number of samples and\n ``n_features`` is the number of features.\n\n cat_vars : int or array of ints, optional (default = None)\n An int or an array containing column indices of categorical\n variable(s)/feature(s) present in the dataset X.\n ``None`` if there are no categorical variables in the dataset.\n\n Returns\n -------\n self : object\n Returns self.\n\n\n transform(X):\n Impute all missing values in X.\n\n Parameters\n ----------\n X : {array-like}, shape = [n_samples, n_features]\n The input data to complete.\n\n Returns\n -------\n X : {array-like}, shape = [n_samples, n_features]\n The imputed dataset.\n\n\n fit_transform(X, y=None, **fit_params):\n Fit MissForest and impute all missing values in X.\n\n Parameters\n ----------\n X : {array-like}, shape (n_samples, n_features)\n Input data, where ``n_samples`` is the number of samples and\n ``n_features`` is the number of features.\n\n Returns\n -------\n X : {array-like}, shape (n_samples, n_features)\n Returns imputed dataset.\n\n### References\n\n* [1] Stekhoven, Daniel J., and Peter B\u00fchlmann. \"MissForest\u2014non-parametric\n missing value imputation for mixed-type data.\" Bioinformatics 28.1\n (2011): 112-118.\n* [2] https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html#sklearn.ensemble.RandomForestRegressor\n* [3] https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/epsilon-machine/missingpy", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "missingpy", "package_url": "https://pypi.org/project/missingpy/", "platform": "", "project_url": "https://pypi.org/project/missingpy/", "project_urls": { "Homepage": "https://github.com/epsilon-machine/missingpy" }, "release_url": "https://pypi.org/project/missingpy/0.2.0/", "requires_dist": null, "requires_python": "", "summary": "Missing Data Imputation for Python", "version": "0.2.0" }, "last_serial": 4578740, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "ffa31e76f202276f7c4177d024c1957b", "sha256": "3d77d8b54f437de0c4230fbbd96dd69ea752162f1847ef0f2de7d1eb919e2eca" }, "downloads": -1, "filename": "missingpy-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "ffa31e76f202276f7c4177d024c1957b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 1359, "upload_time": "2018-07-08T20:08:45", "url": "https://files.pythonhosted.org/packages/74/98/888fdc907c71d89e15b8515aa66e8f804cb06793fb3191667cb854d62262/missingpy-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f076bbcd0d5384b65dfeecbfd0c39255", "sha256": "da2ce19cacd3be423554dd62fe6eda5a59caf72580324fae5ab67172cb591998" }, "downloads": -1, "filename": "missingpy-0.0.1.tar.gz", "has_sig": false, "md5_digest": "f076bbcd0d5384b65dfeecbfd0c39255", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 977, "upload_time": "2018-07-08T20:08:47", "url": "https://files.pythonhosted.org/packages/f0/fb/fdabd00ca17d6e403988dde6034f6da1bac9bc568a197d007927dde9d352/missingpy-0.0.1.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "ef417ce0d7eb618bd5e4729b8cd5c687", "sha256": "0949c984f12925abbaa2a0be4611ad4f2f8c7d911e660ff010badc175dcc057d" }, "downloads": -1, "filename": "missingpy-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ef417ce0d7eb618bd5e4729b8cd5c687", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16742, "upload_time": "2018-07-15T05:15:04", "url": "https://files.pythonhosted.org/packages/65/e3/570b7f183cf1b9209100336ad96a4adcf9f4dc5d6322c56aab09e9b23d57/missingpy-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ea249d24d919eef68b21fbf83c49bc3a", "sha256": "9efd0ade6631f7b65c678041f68476d7ede2048e1f5f240bf527ed78300bcb7c" }, "downloads": -1, "filename": "missingpy-0.1.0.tar.gz", "has_sig": false, "md5_digest": "ea249d24d919eef68b21fbf83c49bc3a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15562, "upload_time": "2018-07-15T05:15:05", "url": "https://files.pythonhosted.org/packages/99/0d/0986d55bef4366fd2779137199b8dab28e2c0b9e4ded9b2afbd61e0f2366/missingpy-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "b6983ca297a440b471a025a658128165", "sha256": "112729629372814d0b274510333f60020fba4cca3d2f5beaee6bbf27ce6fa0b6" }, "downloads": -1, "filename": "missingpy-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b6983ca297a440b471a025a658128165", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16740, "upload_time": "2018-07-15T05:22:52", "url": "https://files.pythonhosted.org/packages/c6/43/9e665e8f517d6e35e88f64c25308878532d9a43a3de16f6fad24bde7cbd8/missingpy-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a160de7d523f4fd3c1212d63caea9a7c", "sha256": "cd1cd03db92729fe7d266d11b460ac718a9d04a4e1326343a9d32cb107e3fb1f" }, "downloads": -1, "filename": "missingpy-0.1.1.tar.gz", "has_sig": false, "md5_digest": "a160de7d523f4fd3c1212d63caea9a7c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15559, "upload_time": "2018-07-15T05:22:53", "url": "https://files.pythonhosted.org/packages/91/77/125b9ec338ec3e9d08e857bfa85c90116e741b67987130e9cc6db3d7510c/missingpy-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "37c96c62c75c102839c18c4fc7723e29", "sha256": "d48fabaaf07284aed704c4e78872a58fdd7f161dd6f71de4cb73c1fe5ecca322" }, "downloads": -1, "filename": "missingpy-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "37c96c62c75c102839c18c4fc7723e29", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 49090, "upload_time": "2018-12-10T04:09:43", "url": "https://files.pythonhosted.org/packages/b5/be/998d04d27054b58f0974b5f09f8457778a0a72d4355e0b7ae877b6cfb850/missingpy-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8ef4daf2e3626f80121308619cb05277", "sha256": "5aacf5b440e443a1cd1eb04ba168402a7a08c3ec5869d2b0130d8d235d8611c1" }, "downloads": -1, "filename": "missingpy-0.2.0.tar.gz", "has_sig": false, "md5_digest": "8ef4daf2e3626f80121308619cb05277", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34236, "upload_time": "2018-12-10T04:09:45", "url": "https://files.pythonhosted.org/packages/20/ef/2c8b77dc55f0e1af9eb9b01ed220abf3957ae205c7b355951a02783416a0/missingpy-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "37c96c62c75c102839c18c4fc7723e29", "sha256": "d48fabaaf07284aed704c4e78872a58fdd7f161dd6f71de4cb73c1fe5ecca322" }, "downloads": -1, "filename": "missingpy-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "37c96c62c75c102839c18c4fc7723e29", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 49090, "upload_time": "2018-12-10T04:09:43", "url": "https://files.pythonhosted.org/packages/b5/be/998d04d27054b58f0974b5f09f8457778a0a72d4355e0b7ae877b6cfb850/missingpy-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8ef4daf2e3626f80121308619cb05277", "sha256": "5aacf5b440e443a1cd1eb04ba168402a7a08c3ec5869d2b0130d8d235d8611c1" }, "downloads": -1, "filename": "missingpy-0.2.0.tar.gz", "has_sig": false, "md5_digest": "8ef4daf2e3626f80121308619cb05277", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34236, "upload_time": "2018-12-10T04:09:45", "url": "https://files.pythonhosted.org/packages/20/ef/2c8b77dc55f0e1af9eb9b01ed220abf3957ae205c7b355951a02783416a0/missingpy-0.2.0.tar.gz" } ] }