diff --git a/examples/pandas.ipynb b/examples/pandas.ipynb
deleted file mode 100644
index 693c1ba..0000000
--- a/examples/pandas.ipynb
+++ /dev/null
@@ -1,1745 +0,0 @@
-{
- "nbformat": 4,
- "nbformat_minor": 0,
- "metadata": {
- "colab": {
- "name": "examples",
- "provenance": [],
- "collapsed_sections": [
- "6YdsVXnwHgfc"
- ]
- },
- "kernelspec": {
- "name": "python3",
- "display_name": "Python 3"
- },
- "language_info": {
- "name": "python"
- }
- },
- "cells": [
- {
- "cell_type": "markdown",
- "source": [
- "# Installation"
- ],
- "metadata": {
- "id": "6YdsVXnwHgfc"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "!pip install cape-privacy==0.3.0 --no-deps"
- ],
- "metadata": {
- "id": "5hfF6zgl8MUL"
- },
- "execution_count": null,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "!pip install anonympy==0.2.0"
- ],
- "metadata": {
- "id": "jo7icbdeoVFe"
- },
- "execution_count": null,
- "outputs": []
- },
- {
- "cell_type": "markdown",
- "source": [
- "#Importing and Initializing"
- ],
- "metadata": {
- "id": "l8hVgsTQsFlL"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "from anonympy.pandas import dfAnonymizer\n",
- "from anonympy.pandas.utils import load_dataset"
- ],
- "metadata": {
- "id": "GcGQR3FW43iP"
- },
- "execution_count": 43,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "# specify datettime columns\n",
- "df = load_dataset('big')\n",
- "\n",
- "anonym = dfAnonymizer(df)\n",
- "\n",
- "anonym"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "C6MnzoxsBiSr",
- "outputId": "02f9b5c3-1344-45a1-9acc-3ec6bb6b010a"
- },
- "execution_count": 78,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "+-------------------------------+\n",
- "| Total number of columns: 10 |\n",
- "+===============================+\n",
- "| Anonymized Column -> Method: |\n",
- "+-------------------------------+\n",
- "| Unanonymized Columns: |\n",
- "| - first_name |\n",
- "| - address |\n",
- "| - city |\n",
- "| - postal |\n",
- "| - phone |\n",
- "| - email |\n",
- "| - web |\n",
- "| - salary |\n",
- "| - birthdate |\n",
- "| - age |\n",
- "+-------------------------------+"
- ]
- },
- "metadata": {},
- "execution_count": 78
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "
So, we have got 10 columns . None of them are yet anonymized
"
- ],
- "metadata": {
- "id": "9VuuD4VuCF9U"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Check dtypes"
- ],
- "metadata": {
- "id": "DdSuJuuLHoYl"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "Since anonymization methods depend on data type, it's recommended to check each column data type before applying any functions
"
- ],
- "metadata": {
- "id": "DquwQyMXC8kC"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "print('Rows:', df.shape[0],'\\nColumns:', df.shape[1])\n",
- "df.head()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 374
- },
- "id": "iy1MFIEzDVmH",
- "outputId": "c53f60a6-aaec-423d-affd-e12a2241792b"
- },
- "execution_count": 45,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "Rows: 500 \n",
- "Columns: 10\n"
- ]
- },
- {
- "output_type": "execute_result",
- "data": {
- "text/html": [
- "\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " first_name \n",
- " address \n",
- " city \n",
- " postal \n",
- " phone \n",
- " email \n",
- " web \n",
- " salary \n",
- " birthdate \n",
- " age \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " 0 \n",
- " Aleshia \n",
- " 14 Taylor St \n",
- " St. Stephens Ward \n",
- " CT2 7PP \n",
- " 01835-703597 \n",
- " atomkiewicz@hotmail.com \n",
- " http://www.alandrosenburgcpapc.co.uk \n",
- " 46391 \n",
- " 2000-12-23 15:09:18.117475200 \n",
- " 21 \n",
- " \n",
- " \n",
- " 1 \n",
- " Evan \n",
- " 5 Binney St \n",
- " Abbey Ward \n",
- " HP11 2AX \n",
- " 01937-864715 \n",
- " evan.zigomalas@gmail.com \n",
- " http://www.capgeminiamerica.co.uk \n",
- " 30798 \n",
- " 2004-04-22 04:09:51.325948800 \n",
- " 17 \n",
- " \n",
- " \n",
- " 2 \n",
- " France \n",
- " 8 Moor Place \n",
- " East Southbourne and Tuckton W \n",
- " BH6 3BE \n",
- " 01347-368222 \n",
- " france.andrade@hotmail.com \n",
- " http://www.elliottjohnwesq.co.uk \n",
- " 32384 \n",
- " 2002-01-21 18:56:29.090025600 \n",
- " 19 \n",
- " \n",
- " \n",
- " 3 \n",
- " Ulysses \n",
- " 505 Exeter Rd \n",
- " Hawerby cum Beesby \n",
- " DN36 5RP \n",
- " 01912-771311 \n",
- " ulysses@hotmail.com \n",
- " http://www.mcmahanbenl.co.uk \n",
- " 39298 \n",
- " 2000-11-24 21:59:48.621840000 \n",
- " 21 \n",
- " \n",
- " \n",
- " 4 \n",
- " Tyisha \n",
- " 5396 Forth Street \n",
- " Greets Green and Lyng Ward \n",
- " B70 9DT \n",
- " 01547-429341 \n",
- " tyisha.veness@hotmail.com \n",
- " http://www.champagneroom.co.uk \n",
- " 41630 \n",
- " 1998-06-23 05:19:37.687008000 \n",
- " 23 \n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " "
- ],
- "text/plain": [
- " first_name address ... birthdate age\n",
- "0 Aleshia 14 Taylor St ... 2000-12-23 15:09:18.117475200 21\n",
- "1 Evan 5 Binney St ... 2004-04-22 04:09:51.325948800 17\n",
- "2 France 8 Moor Place ... 2002-01-21 18:56:29.090025600 19\n",
- "3 Ulysses 505 Exeter Rd ... 2000-11-24 21:59:48.621840000 21\n",
- "4 Tyisha 5396 Forth Street ... 1998-06-23 05:19:37.687008000 23\n",
- "\n",
- "[5 rows x 10 columns]"
- ]
- },
- "metadata": {},
- "execution_count": 45
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "print('Categorical Columns: ', anonym.categorical_columns)\n",
- "print('Numeric Columns: ', anonym.numeric_columns)\n",
- "print('Datetime Columns: ', anonym.datetime_columns)\n",
- "\n",
- "print('\\nOr Call `info` method\\n ')\n",
- "\n",
- "anonym.info()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "IheXU6FtC19U",
- "outputId": "0dbd3eef-7621-48d1-b42c-e0227f82f6fb"
- },
- "execution_count": 46,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "Categorical Columns: ['first_name', 'address', 'city', 'postal', 'phone', 'email', 'web']\n",
- "Numeric Columns: ['salary', 'age']\n",
- "Datetime Columns: ['birthdate']\n",
- "\n",
- "Or Call `info` method\n",
- " \n",
- "+------------+--------+-------------+--------+\n",
- "| Column | Status | Type | Method |\n",
- "+============+========+=============+========+\n",
- "| first_name | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| address | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| city | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| postal | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| phone | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| email | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| web | 0 | categorical | |\n",
- "+------------+--------+-------------+--------+\n",
- "| salary | 0 | numeric | |\n",
- "+------------+--------+-------------+--------+\n",
- "| birthdate | 0 | datetime | |\n",
- "+------------+--------+-------------+--------+\n",
- "| age | 0 | numeric | |\n",
- "+------------+--------+-------------+--------+\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "7 categorical, 2 numerical and 1 datetime columns. \n",
- "Let's see what methods we can apply to categorical columns.\n",
- " List of available methods: anonympy.pandas.utils.available_methods
\n",
- "
"
- ],
- "metadata": {
- "id": "9jBf13NXD8RS"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "from anonympy.pandas.utils import available_methods"
- ],
- "metadata": {
- "id": "e1Yey5BGDuLG"
- },
- "execution_count": 47,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "available_methods('categorical') # args: 'categorical' / 'numerical' / 'datetime' / 'general' / None"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "t2gqFZdoEU9K",
- "outputId": "843b2a43-2d99-438b-8023-74e012e09dfd"
- },
- "execution_count": 48,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "categorical_fake\tcategorical_fake_auto\tcategorical_resampling\tcategorical_tokenization\tcategorical_email_masking\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Categorical Email Masking\n",
- "\n",
- "To apply partial email masking call categorical_email_masking
on corresponding column
"
- ],
- "metadata": {
- "id": "vIr7XFBoSoDh"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.categorical_email_masking(columns='email', inplace = False)"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "Lxbx7cmbSquq",
- "outputId": "32075f7e-76d3-45e0-9865-124ba8bd147a"
- },
- "execution_count": 49,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "0 a*****z@hotmail.com\n",
- "1 e*****s@gmail.com\n",
- "2 f*****e@hotmail.com\n",
- "3 u*****s@hotmail.com\n",
- "4 t*****s@hotmail.com\n",
- " ... \n",
- "495 a*****y@veit.co.uk\n",
- "496 r*****i@euresti.co.uk\n",
- "497 c*****g@brenning.co.uk\n",
- "498 c*****y@gmail.com\n",
- "499 m*****i@hotmail.com\n",
- "Name: email, Length: 500, dtype: object"
- ]
- },
- "metadata": {},
- "execution_count": 49
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "`inplace=True` (default) - changes will be applied to the dataframe. Access using `anonym.to_df()`\n",
- " \n",
- "`inplace = False` - return the changes"
- ],
- "metadata": {
- "id": "ma_Bf0IATgyc"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.categorical_email_masking('email') # inplace = True\n",
- "\n",
- "print(anonym.anonymized_columns, '\\n')\n",
- "\n",
- "print(anonym)"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "u--sEHaXTfMs",
- "outputId": "ed34ea67-c8a5-42ac-ec38-3944eb191851"
- },
- "execution_count": 50,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "['email'] \n",
- "\n",
- "+-------------------------------+\n",
- "| Total number of columns: 10 |\n",
- "+===============================+\n",
- "| Anonymized Column -> Method: |\n",
- "| - email -> Partial Masking |\n",
- "+-------------------------------+\n",
- "| Unanonymized Columns: |\n",
- "| - first_name |\n",
- "| - address |\n",
- "| - city |\n",
- "| - postal |\n",
- "| - phone |\n",
- "| - web |\n",
- "| - salary |\n",
- "| - birthdate |\n",
- "| - age |\n",
- "+-------------------------------+\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "Now **email** column appears to be anonymized"
- ],
- "metadata": {
- "id": "wYK1onhthhc-"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Categorical Synthetic data (fake data) \n",
- "Next, let's replace some values with synthetically generated ones. \n",
- " If column name is same as the corresponding faker's method, use categorical_fake_auto method.\n",
- " List of faker's methods: anonympy.pandas.utils.fake_methods
\n",
- "
"
- ],
- "metadata": {
- "id": "JCgS0Zr0F_ni"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "from anonympy.pandas.utils import fake_methods"
- ],
- "metadata": {
- "id": "5nn0FVkWEyd0"
- },
- "execution_count": 51,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "fake_methods() # args: letter / None/ 'all'\n",
- "# output in the following screenshot"
- ],
- "metadata": {
- "id": "0t36isKIHgd-",
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "outputId": "bd13d825-3d93-4ec6-890c-72fd239fb9b9"
- },
- "execution_count": 52,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "A | aba, address, administrative_unit, am_pm, android_platform_token, ascii_company_email, ascii_email, ascii_free_email, ascii_safe_email\n",
- "B | bank_country, bban, boolean, bothify, bs, building_number\n",
- "C | cache_pattern, catch_phrase, century, chrome, city, city_prefix, city_suffix, color, color_name, company, company_email, company_suffix, coordinate, country, country_calling_code, country_code, credit_card_expire, credit_card_full, credit_card_number, credit_card_provider, credit_card_security_code, cryptocurrency, cryptocurrency_code, cryptocurrency_name, csv, currency, currency_code, currency_name, currency_symbol, current_country, current_country_code\n",
- "D | date, date_between, date_between_dates, date_object, date_of_birth, date_this_century, date_this_decade, date_this_month, date_this_year, date_time, date_time_ad, date_time_between, date_time_between_dates, date_time_this_century, date_time_this_decade, date_time_this_month, date_time_this_year, day_of_month, day_of_week, del_arguments, dga, domain_name, domain_word, dsv\n",
- "E | ean, ean13, ean8, ein, email\n",
- "F | factories, file_extension, file_name, file_path, firefox, first_name, first_name_female, first_name_male, first_name_nonbinary, fixed_width, format, free_email, free_email_domain, future_date, future_datetime\n",
- "G | generator_attrs, get_arguments, get_formatter, get_providers\n",
- "H | hex_color, hexify, hostname, http_method\n",
- "I | iana_id, iban, image, image_url, internet_explorer, invalid_ssn, ios_platform_token, ipv4, ipv4_network_class, ipv4_private, ipv4_public, ipv6, isbn10, isbn13, iso8601, items, itin\n",
- "J | job, json\n",
- "L | language_code, language_name, last_name, last_name_female, last_name_male, last_name_nonbinary, latitude, latlng, lexify, license_plate, linux_platform_token, linux_processor, local_latlng, locale, locales, localized_ean, localized_ean13, localized_ean8, location_on_land, longitude\n",
- "M | mac_address, mac_platform_token, mac_processor, md5, military_apo, military_dpo, military_ship, military_state, mime_type, month, month_name, msisdn\n",
- "N | name, name_female, name_male, name_nonbinary, nic_handle, nic_handles, null_boolean, numerify\n",
- "O | opera\n",
- "P | paragraph, paragraphs, parse, password, past_date, past_datetime, phone_number, port_number, postalcode, postalcode_in_state, postalcode_plus4, postcode, postcode_in_state, prefix, prefix_female, prefix_male, prefix_nonbinary, pricetag, profile, provider, providers, psv, pybool, pydecimal, pydict, pyfloat, pyint, pyiterable, pylist, pyset, pystr, pystr_format, pystruct, pytimezone, pytuple\n",
- "R | random, random_choices, random_digit, random_digit_not_null, random_digit_not_null_or_empty, random_digit_or_empty, random_element, random_elements, random_int, random_letter, random_letters, random_lowercase_letter, random_number, random_sample, random_uppercase_letter, randomize_nb_elements, rgb_color, rgb_css_color, ripe_id\n",
- "S | safari, safe_color_name, safe_domain_name, safe_email, safe_hex_color, secondary_address, seed_instance, seed_locale, sentence, sentences, set_arguments, set_formatter, sha1, sha256, simple_profile, slug, ssn, state, state_abbr, street_address, street_name, street_suffix, suffix, suffix_female, suffix_male, suffix_nonbinary, swift, swift11, swift8\n",
- "T | tar, text, texts, time, time_delta, time_object, time_series, timezone, tld, tsv\n",
- "U | unique, unix_device, unix_partition, unix_time, upc_a, upc_e, uri, uri_extension, uri_page, uri_path, url, user_agent, user_name, uuid4\n",
- "W | weights, windows_platform_token, word, words\n",
- "Y | year\n",
- "Z | zipcode, zipcode_in_state, zipcode_plus4\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "As we can see from this list, column names: **address**, **city** and **first_name** correspond to faker's methods. So we can run `categorical_fake_auto` and it will anonymize these 3 columns\n",
- "* `email` method is also there, but since we already anonymized it, it won't get affected.\n",
- "\n",
- "![image.png](data:image/png;base64,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)"
- ],
- "metadata": {
- "id": "Efy7zl9xJjGh"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.categorical_fake_auto() # default args: locale='en_US', inplace=True\n",
- "\n",
- "# we could use `categorical_fake` method as well, with specifiying the columns\n",
- "# anonym.categorical_fake(['first_name', 'address', 'city'])\n",
- "\n",
- "print(anonym)"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "1h4uErHyJoCZ",
- "outputId": "c83dd408-c618-478f-8a6b-2193df46afba"
- },
- "execution_count": 53,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "`email` column already anonymized!\n",
- "+--------------------------------+\n",
- "| Total number of columns: 10 |\n",
- "+================================+\n",
- "| Anonymized Column -> Method: |\n",
- "| - email -> Partial Masking |\n",
- "| - first_name -> Synthetic Data |\n",
- "| - address -> Synthetic Data |\n",
- "| - city -> Synthetic Data |\n",
- "+--------------------------------+\n",
- "| Unanonymized Columns: |\n",
- "| - postal |\n",
- "| - phone |\n",
- "| - web |\n",
- "| - salary |\n",
- "| - birthdate |\n",
- "| - age |\n",
- "+--------------------------------+\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "Let's call `fake_methods` for letter 'u'"
- ],
- "metadata": {
- "id": "ezXj21Kwj5xk"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "fake_methods('u')"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "g-fVpOSVj5Or",
- "outputId": "fac57759-8a09-4b5b-bf48-9e2063f9f70c"
- },
- "execution_count": 54,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- " unique, unix_device, unix_partition, unix_time, upc_a, upc_e, uri, uri_extension, uri_page, uri_path, url, user_agent, user_name, uuid4\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "In our dataframe '**web**' column column stored different **urls**. So we can use `url` method on '**web**' column. \n",
- "\n",
- "And column '**phone**' values can be replaced using `phone_number` method\n",
- "\n",
- "Let's apply these changes using `categorical_fake` method which accepts list of column names (if similar to method name) or a dictionary (when names differ)"
- ],
- "metadata": {
- "id": "1GSUKASskUMN"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.categorical_fake({'web':'url', 'phone': 'phone_number'}) # inplace = True\n",
- "\n",
- "anonym.info()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "9xOiIlg0koNv",
- "outputId": "d52a595e-d196-47e6-b282-f8113139b1b6"
- },
- "execution_count": 55,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "+------------+--------+-------------+-----------------+\n",
- "| Column | Status | Type | Method |\n",
- "+============+========+=============+=================+\n",
- "| first_name | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| address | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| city | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| postal | 0 | categorical | |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| phone | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| email | 1 | categorical | Partial Masking |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| web | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| salary | 0 | numeric | |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| birthdate | 0 | datetime | |\n",
- "+------------+--------+-------------+-----------------+\n",
- "| age | 0 | numeric | |\n",
- "+------------+--------+-------------+-----------------+\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Categorical Tokenization\n"
- ],
- "metadata": {
- "id": "NKODUxOmn1fk"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "Let's apply tokenization on '**postal**' column"
- ],
- "metadata": {
- "id": "md6pqB-boElC"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "print(anonym.categorical_tokenization('postal', inplace = False)) # first inplace = False, to see how the changes will look\n",
- "\n",
- "anonym.categorical_tokenization('postal') # inplace = True, by default"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "VhHUGjftoA-U",
- "outputId": "eaf39bdd-562a-41a8-aaa7-d5398e3b7e7b"
- },
- "execution_count": 56,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "0 2a8ba32381\n",
- "1 1569763104\n",
- "2 73c0b907be\n",
- "3 b155a02362\n",
- "4 56a6b1e03a\n",
- " ... \n",
- "495 7687741a49\n",
- "496 6a16bbf755\n",
- "497 bedd62bb14\n",
- "498 30dae3be6e\n",
- "499 7c49b8248b\n",
- "Name: postal, Length: 500, dtype: object\n"
- ]
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "# which columns are left unanonymized? \n",
- "print(anonym.unanonymized_columns)"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "rO1SI4H2pXyr",
- "outputId": "0eeb5fe6-d51e-4b22-ae6a-e8a531c50097"
- },
- "execution_count": 58,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "['salary', 'birthdate', 'age']\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Datetime Perturbation (noise)"
- ],
- "metadata": {
- "id": "x301iHA7peji"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "Let's add some random noise to '**birthdate**' column\n",
- " Also, we should specify to add noise only to days and month but not year."
- ],
- "metadata": {
- "id": "NWLhBATkpk20"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "print(anonym.datetime_noise('birthdate', frequency=('MONTH', 'DAY'), inplace = False), '\\n') # inplace = False to observe the changes\n",
- "\n",
- "print(df.birthdate) # for comparison"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "mcS3tL6kpgd3",
- "outputId": "2be407a8-2f95-4d57-feb0-85ee8f3702ce"
- },
- "execution_count": 65,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "0 2000-03-30 15:09:18.117475200\n",
- "1 2004-05-18 04:09:51.325948800\n",
- "2 2002-07-15 18:56:29.090025600\n",
- "3 2000-11-19 21:59:48.621840000\n",
- "4 1998-05-20 05:19:37.687008000\n",
- " ... \n",
- "495 1994-09-15 16:40:58.379318400\n",
- "496 1998-11-08 11:23:56.188204800\n",
- "497 1998-06-12 22:03:29.331331200\n",
- "498 1995-02-15 21:48:38.237414400\n",
- "499 2000-10-12 20:38:06.739699200\n",
- "Name: birthdate, Length: 500, dtype: datetime64[ns] \n",
- "\n",
- "0 2000-12-23 15:09:18.117475200\n",
- "1 2004-04-22 04:09:51.325948800\n",
- "2 2002-01-21 18:56:29.090025600\n",
- "3 2000-11-24 21:59:48.621840000\n",
- "4 1998-06-23 05:19:37.687008000\n",
- " ... \n",
- "495 1995-06-08 16:40:58.379318400\n",
- "496 1999-02-10 11:23:56.188204800\n",
- "497 1998-01-13 22:03:29.331331200\n",
- "498 1994-12-20 21:48:38.237414400\n",
- "499 2000-02-13 20:38:06.739699200\n",
- "Name: birthdate, Length: 500, dtype: datetime64[ns]\n"
- ]
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.datetime_noise('birthdate', frequency=('MONTH', 'DAY')) # inplace=True, to apply the changes"
- ],
- "metadata": {
- "id": "rKmHk_aVqv3f"
- },
- "execution_count": null,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.info()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "mWsbXFSCq1FY",
- "outputId": "63581894-6f72-4517-f1b0-29398f892db7"
- },
- "execution_count": 67,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "+------------+--------+-------------+-----------------------+\n",
- "| Column | Status | Type | Method |\n",
- "+============+========+=============+=======================+\n",
- "| first_name | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| address | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| city | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| postal | 1 | categorical | Tokenization |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| phone | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| email | 1 | categorical | Partial Masking |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| web | 1 | categorical | Synthetic Data |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| salary | 0 | numeric | |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| birthdate | 1 | datetime | Datetime Perturbation |\n",
- "+------------+--------+-------------+-----------------------+\n",
- "| age | 0 | numeric | |\n",
- "+------------+--------+-------------+-----------------------+\n"
- ]
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "Two numeric columns: '**salary**' and '**age**' are left"
- ],
- "metadata": {
- "id": "5E4QdD_oq3hK"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Numeric Rounding "
- ],
- "metadata": {
- "id": "m6YhI21CrDVE"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- "Applying `numeric_rounding` to '**salary**' column"
- ],
- "metadata": {
- "id": "EHkjZIYOsNvt"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "print(df.salary, '\\n') # original\n",
- "anonym.numeric_rounding('salary', inplace = False) # see the changes"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "6rqrKURWrGAg",
- "outputId": "b9b7a53f-73a3-4f13-99ba-6e07dd20242e"
- },
- "execution_count": 68,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "0 46391\n",
- "1 30798\n",
- "2 32384\n",
- "3 39298\n",
- "4 41630\n",
- " ... \n",
- "495 42239\n",
- "496 42640\n",
- "497 44982\n",
- "498 32827\n",
- "499 41266\n",
- "Name: salary, Length: 500, dtype: int64 \n",
- "\n"
- ]
- },
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "0 50000\n",
- "1 30000\n",
- "2 30000\n",
- "3 40000\n",
- "4 40000\n",
- " ... \n",
- "495 40000\n",
- "496 40000\n",
- "497 40000\n",
- "498 30000\n",
- "499 40000\n",
- "Name: salary, Length: 500, dtype: int64"
- ]
- },
- "metadata": {},
- "execution_count": 68
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.numeric_rounding('salary') # apply the changes"
- ],
- "metadata": {
- "id": "XE1rXt4-r-I1"
- },
- "execution_count": 69,
- "outputs": []
- },
- {
- "cell_type": "markdown",
- "source": [
- "# Numeric Perturbation (noise)"
- ],
- "metadata": {
- "id": "jx4zer-nsGBr"
- }
- },
- {
- "cell_type": "markdown",
- "source": [
- " Some noise to '**age**' column would be nice"
- ],
- "metadata": {
- "id": "P3SwYoXcs_a1"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "print(df.age, '\\n') # original\n",
- "\n",
- "print(anonym.numeric_noise('age', inplace = False)) # observe the changes"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "PU5fy0wXsJx6",
- "outputId": "acd07350-4d94-4555-aaa5-f8c9bd21b21a"
- },
- "execution_count": 71,
- "outputs": [
- {
- "output_type": "stream",
- "name": "stdout",
- "text": [
- "0 21\n",
- "1 17\n",
- "2 19\n",
- "3 21\n",
- "4 23\n",
- " ..\n",
- "495 26\n",
- "496 22\n",
- "497 23\n",
- "498 27\n",
- "499 21\n",
- "Name: age, Length: 500, dtype: int64 \n",
- "\n",
- "0 28\n",
- "1 17\n",
- "2 25\n",
- "3 26\n",
- "4 17\n",
- " ..\n",
- "495 17\n",
- "496 19\n",
- "497 25\n",
- "498 21\n",
- "499 28\n",
- "Length: 500, dtype: int64\n"
- ]
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.numeric_noise('age') # apply the changes"
- ],
- "metadata": {
- "id": "moJtlWantd4d"
- },
- "execution_count": 72,
- "outputs": []
- },
- {
- "cell_type": "code",
- "source": [
- "anonym"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "g8Whzhwmtui2",
- "outputId": "17bda6eb-0655-4be0-d8e7-4a369e3ddbd5"
- },
- "execution_count": 73,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "+---------------------------------------+\n",
- "| Total number of columns: 10 |\n",
- "+=======================================+\n",
- "| Anonymized Column -> Method: |\n",
- "| - email -> Partial Masking |\n",
- "| - first_name -> Synthetic Data |\n",
- "| - address -> Synthetic Data |\n",
- "| - city -> Synthetic Data |\n",
- "| - web -> Synthetic Data |\n",
- "| - phone -> Synthetic Data |\n",
- "| - postal -> Tokenization |\n",
- "| - birthdate -> Datetime Perturbation |\n",
- "| - salary -> Generalization - Rounding |\n",
- "| - age -> Numeric Perturbation |\n",
- "+---------------------------------------+\n",
- "| Unanonymized Columns: |\n",
- "| |\n",
- "+---------------------------------------+"
- ]
- },
- "metadata": {},
- "execution_count": 73
- }
- ]
- },
- {
- "cell_type": "markdown",
- "source": [
- "All columns have been successfully anonymized, let's now compare both datasets before and after anonymization "
- ],
- "metadata": {
- "id": "Fx5pcH7YtxSU"
- }
- },
- {
- "cell_type": "code",
- "source": [
- "df.head()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 337
- },
- "id": "aUhWIBF9twM1",
- "outputId": "1c1b74bc-753d-4347-c871-c1d492f2942d"
- },
- "execution_count": 76,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/html": [
- "\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " first_name \n",
- " address \n",
- " city \n",
- " postal \n",
- " phone \n",
- " email \n",
- " web \n",
- " salary \n",
- " birthdate \n",
- " age \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " 0 \n",
- " Aleshia \n",
- " 14 Taylor St \n",
- " St. Stephens Ward \n",
- " CT2 7PP \n",
- " 01835-703597 \n",
- " atomkiewicz@hotmail.com \n",
- " http://www.alandrosenburgcpapc.co.uk \n",
- " 46391 \n",
- " 2000-12-23 15:09:18.117475200 \n",
- " 21 \n",
- " \n",
- " \n",
- " 1 \n",
- " Evan \n",
- " 5 Binney St \n",
- " Abbey Ward \n",
- " HP11 2AX \n",
- " 01937-864715 \n",
- " evan.zigomalas@gmail.com \n",
- " http://www.capgeminiamerica.co.uk \n",
- " 30798 \n",
- " 2004-04-22 04:09:51.325948800 \n",
- " 17 \n",
- " \n",
- " \n",
- " 2 \n",
- " France \n",
- " 8 Moor Place \n",
- " East Southbourne and Tuckton W \n",
- " BH6 3BE \n",
- " 01347-368222 \n",
- " france.andrade@hotmail.com \n",
- " http://www.elliottjohnwesq.co.uk \n",
- " 32384 \n",
- " 2002-01-21 18:56:29.090025600 \n",
- " 19 \n",
- " \n",
- " \n",
- " 3 \n",
- " Ulysses \n",
- " 505 Exeter Rd \n",
- " Hawerby cum Beesby \n",
- " DN36 5RP \n",
- " 01912-771311 \n",
- " ulysses@hotmail.com \n",
- " http://www.mcmahanbenl.co.uk \n",
- " 39298 \n",
- " 2000-11-24 21:59:48.621840000 \n",
- " 21 \n",
- " \n",
- " \n",
- " 4 \n",
- " Tyisha \n",
- " 5396 Forth Street \n",
- " Greets Green and Lyng Ward \n",
- " B70 9DT \n",
- " 01547-429341 \n",
- " tyisha.veness@hotmail.com \n",
- " http://www.champagneroom.co.uk \n",
- " 41630 \n",
- " 1998-06-23 05:19:37.687008000 \n",
- " 23 \n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " "
- ],
- "text/plain": [
- " first_name address ... birthdate age\n",
- "0 Aleshia 14 Taylor St ... 2000-12-23 15:09:18.117475200 21\n",
- "1 Evan 5 Binney St ... 2004-04-22 04:09:51.325948800 17\n",
- "2 France 8 Moor Place ... 2002-01-21 18:56:29.090025600 19\n",
- "3 Ulysses 505 Exeter Rd ... 2000-11-24 21:59:48.621840000 21\n",
- "4 Tyisha 5396 Forth Street ... 1998-06-23 05:19:37.687008000 23\n",
- "\n",
- "[5 rows x 10 columns]"
- ]
- },
- "metadata": {},
- "execution_count": 76
- }
- ]
- },
- {
- "cell_type": "code",
- "source": [
- "anonym.to_df()"
- ],
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 867
- },
- "id": "A_qehCevuDJG",
- "outputId": "cdb70418-89db-4bdc-c4ef-87c8326b406f"
- },
- "execution_count": 77,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/html": [
- "\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " first_name \n",
- " address \n",
- " city \n",
- " postal \n",
- " phone \n",
- " email \n",
- " web \n",
- " salary \n",
- " birthdate \n",
- " age \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " 0 \n",
- " Betty \n",
- " 037 Anderson Branch Apt. 184\\nPowellfurt, AL 5... \n",
- " Annside \n",
- " ac9296b7cd \n",
- " +1-669-652-5362x575 \n",
- " a*****z@hotmail.com \n",
- " http://wilson.com/ \n",
- " 50000 \n",
- " 2001-02-21 15:09:18.117475200 \n",
- " 23 \n",
- " \n",
- " \n",
- " 1 \n",
- " Dustin \n",
- " 32977 Amy Shores\\nNorth Jessicatown, WV 01498 \n",
- " North Andrew \n",
- " 3ed9f4641e \n",
- " 737-362-3685 \n",
- " e*****s@gmail.com \n",
- " http://meyer.com/ \n",
- " 30000 \n",
- " 2004-02-26 04:09:51.325948800 \n",
- " 8 \n",
- " \n",
- " \n",
- " 2 \n",
- " Christopher \n",
- " 7854 Nunez Cove\\nHoodside, SC 05482 \n",
- " Hughesside \n",
- " cc1f446ef9 \n",
- " +1-145-640-8718 \n",
- " f*****e@hotmail.com \n",
- " http://cross.info/ \n",
- " 30000 \n",
- " 2001-08-28 18:56:29.090025600 \n",
- " 15 \n",
- " \n",
- " \n",
- " 3 \n",
- " Samuel \n",
- " 7583 Heather Prairie\\nScotthaven, AR 94542 \n",
- " West Ashley \n",
- " bc69e5439a \n",
- " (719)299-8553x6456 \n",
- " u*****s@hotmail.com \n",
- " https://www.anderson.com/ \n",
- " 40000 \n",
- " 2000-12-25 21:59:48.621840000 \n",
- " 21 \n",
- " \n",
- " \n",
- " 4 \n",
- " Timothy \n",
- " 929 Ellis Hills Apt. 766\\nEast Elizabeth, MO 2... \n",
- " Reesemouth \n",
- " f1e506bf00 \n",
- " 041.810.3076 \n",
- " t*****s@hotmail.com \n",
- " https://www.shannon-thomas.net/ \n",
- " 40000 \n",
- " 1999-03-24 05:19:37.687008000 \n",
- " 23 \n",
- " \n",
- " \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " ... \n",
- " \n",
- " \n",
- " 495 \n",
- " Natalie \n",
- " 54840 Tate Summit Suite 754\\nLake Amberbury, W... \n",
- " Port Jacobstad \n",
- " da31a1d471 \n",
- " 001-170-972-2673x3215 \n",
- " a*****y@veit.co.uk \n",
- " https://www.moore.com/ \n",
- " 40000 \n",
- " 1995-10-09 16:40:58.379318400 \n",
- " 20 \n",
- " \n",
- " \n",
- " 496 \n",
- " Jose \n",
- " 847 Henson Pike Apt. 762\\nPort Nicholashaven, ... \n",
- " Peterport \n",
- " 11f990c971 \n",
- " 127-355-3556x6363 \n",
- " r*****i@euresti.co.uk \n",
- " http://perry.com/ \n",
- " 40000 \n",
- " 1999-06-12 11:23:56.188204800 \n",
- " 17 \n",
- " \n",
- " \n",
- " 497 \n",
- " Joanna \n",
- " 942 Derek Orchard\\nNew Dawntown, PA 88841 \n",
- " Port Dannyborough \n",
- " 33daacb57b \n",
- " +1-048-563-2513x3377 \n",
- " c*****g@brenning.co.uk \n",
- " http://www.bradley.com/ \n",
- " 40000 \n",
- " 1997-05-20 22:03:29.331331200 \n",
- " 32 \n",
- " \n",
- " \n",
- " 498 \n",
- " Karen \n",
- " 50796 Karen Fall\\nSouth Whitney, NY 24702 \n",
- " Brownview \n",
- " 76fbf0ca46 \n",
- " 001-142-681-2195x7266 \n",
- " c*****y@gmail.com \n",
- " https://www.carr.org/ \n",
- " 30000 \n",
- " 1994-02-23 21:48:38.237414400 \n",
- " 27 \n",
- " \n",
- " \n",
- " 499 \n",
- " Melissa \n",
- " PSC 0277, Box 3447\\nAPO AP 93784 \n",
- " Ramosside \n",
- " 93cd3124ab \n",
- " (550)786-3496 \n",
- " m*****i@hotmail.com \n",
- " https://levy.com/ \n",
- " 40000 \n",
- " 2000-07-15 20:38:06.739699200 \n",
- " 17 \n",
- " \n",
- " \n",
- "
\n",
- "
500 rows × 10 columns
\n",
- "
\n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " "
- ],
- "text/plain": [
- " first_name ... age\n",
- "0 Betty ... 23\n",
- "1 Dustin ... 8\n",
- "2 Christopher ... 15\n",
- "3 Samuel ... 21\n",
- "4 Timothy ... 23\n",
- ".. ... ... ..\n",
- "495 Natalie ... 20\n",
- "496 Jose ... 17\n",
- "497 Joanna ... 32\n",
- "498 Karen ... 27\n",
- "499 Melissa ... 17\n",
- "\n",
- "[500 rows x 10 columns]"
- ]
- },
- "metadata": {},
- "execution_count": 77
- }
- ]
- }
- ]
-}
\ No newline at end of file