Skip to main content

k-anonymity package

Evaluate if a tabular dataset respect k-anonymity handling missing values in the dataset. K-anonymity stands for having at least k similar rows for each row in the dataset, including itself. A missing value has value of any other category, having missing values increase the deidentification. This package includes a function to add the minimum number of missing values to reach k-anonymity of the dataset.

Installation

uv add kanonymity

Important information

The current version of the pipeline does not directly handle longitudinal data. You should take care of deciding how to consider duplicates subjects. One example here, where it is decided to keep most common answer, but you could also decide to replace answers that changes accross one subject by missing value, or consider the different rows as different individuals:

# df is the original complete dataframe
# replace "subject_id" by the name of the ID column
# quasi_identifiers is a list of quasi-identifiers column names
# index_table helps to reduplicate rows in the end in case some modification of the dataframe is done
table = df.groupby(["subject_id"]+quasi_identifiers, dropna=False).size().to_frame('size').reset_index()
index_table = df.groupby(['subject_id'], dropna=False).apply(lambda x: x.index.tolist()).to_frame('original_index').reset_index()
index_table = index_table.sort_values(['subject_id'], ascending=[True])
df = table.sort_values(["subject_id", "size"], ascending=[True, False]).drop_duplicates(subset=["subject_id"], keep="first")
df = df.drop('size', axis=1)

Here is how to reduplicate the subjects that had several rows in the original dataset:

# df is the new version of the deduplicated dataset that had potential modifications to increase deidentification
# original_df is the dataframe before these potential modifications
for r in range(len(df)):
    if not original_df.iloc[r].equals(df.iloc[r]):
        indexes = index_table['original_index'].iloc[r]
        for i in indexes:
            for feature in quasi_identifiers:
                if feature.split('_')[0] not in numerical_QI:
                    flat_df.loc[i, feature] = df[feature].iloc[r]
                else:
                    if original_df[feature].iloc[r] != df[feature].iloc[r]:
                        flat_df[feature.split('_')[0]].iloc[i] = np.nan

In addition, the quasi-identifiers have to be categorical columns. You can use relevant bins to convert numerical to categorical.

Functions details

  • check_k_anonymity(df, quasi_identifier_cols, k) returns the number of rows that don't have enough similar rows, and are at risk of reidentification. The columns to considere are given in a list quasi_identifers_cols and the number of similar rows to have, including the row itself is k. It also returns a summary df of every combination of each categories combinations that exists in the dataset. Missing values are counting as if they could be any existing category. If a feature A can have 0 or 1 as categories, a row with missing A would count as two rows, one with 0 and one with 1.
  • safe_combinations(df, quasi_identifiers, k, min_combi_size=2, max_combi_size=None) checks which combinations of features validates k-anonymity. In case you have a large number of quasi-identifiers, you can set boundaries to the number of features to consider in your combinations. The result is given as a list of lists.
  • min_missingness_max_deid(df, QI, k, maximum_missingness=25, excluded_features=None, step=0.001, n_random_trials=25) adds the same percentage of missing values in every quasi-identifier feature, with a maximum of maximum_missingness to reach no risk of reidentification. Binary search is implemented to find the lowest percentage that allows no risk of reidentification, with several random trials as the position of the missing values impacts the k-anonymity. The step defines the precision of the percentage and the function allows to exclude some columns from the missingness addition. If the maximum_missingness threshold doesn't allow to earase the risk of reidentification, it returns the dataframe with the minimum number of rows at risk of reidentification. The function returns the most deidentified dataframe with the minimum addition of missingness possible, the percentage of missingness added to each column and the number of rows that are at risk of reidentification.

Metadata

Release files for kanonymity 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kanonymity 0.1.0
File Size Uploaded Provenance Actions
kanonymity-0.1.0.tar.gz 7.6 kB Without provenance Details for kanonymity-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for kanonymity 0.1.0
File Interpreter ABI Platform Actions
kanonymity-0.1.0-py3-none-any.whl Python 3 none any Details for kanonymity-0.1.0-py3-none-any.whl

Total release size: 13.7 kB

Release files / kanonymity-0.1.0.tar.gz

Download URL kanonymity-0.1.0.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d62ce1c9508093a4e0f1ca7df88eca341efe47804625470bd6d95675dca6690e
BLAKE2b-256 checksum
How to use checksums
4e231faf9d312e8b9e1ac5245c5bc8b5f616bbfcbc410f65e5cb12e057b5e068
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / kanonymity-0.1.0-py3-none-any.whl

Download URL kanonymity-0.1.0-py3-none-any.whl
Size 6.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eb2b179958a466065dce6b8876846c30b2411e09a9e5f5623d521bbeb51510f2
BLAKE2b-256 checksum
How to use checksums
9668d3f10d7b8d55bbdd5353aec983c3947763addb42dbf8b7354c39d0ac1407
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for kanonymity 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page