idscrub 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
test/conftest.py ADDED
@@ -0,0 +1,12 @@
1
+ import pytest
2
+ from idscrub import IDScrub
3
+
4
+
5
+ @pytest.fixture
6
+ def scrub_object():
7
+ return IDScrub(
8
+ [
9
+ "Our names are Hamish McDonald, L. Salah, and Elena Suárez.",
10
+ "My number is +441111111111 and I live at AA11 1AA.",
11
+ ]
12
+ )
test/test_all.py ADDED
@@ -0,0 +1,39 @@
1
+ import pandas as pd
2
+ from idscrub import IDScrub
3
+ from pandas.testing import assert_frame_equal
4
+
5
+
6
+ # Note: These tests will fail if the kernel has not been restarted since the SpaCy model was downloaded.
7
+ def test_all(scrub_object):
8
+ scrubbed = scrub_object.all()
9
+ assert scrubbed == [
10
+ "Our names are [PERSON], [PERSON], and [PERSON].",
11
+ "My number is [PHONENO] and I live at [POSTCODE].",
12
+ ]
13
+
14
+
15
+ def test_text_id():
16
+ scrub = IDScrub(["Our names are Hamish McDonald, L. Salah, and Elena Suárez."] * 10)
17
+
18
+ scrub.all()
19
+
20
+ df = scrub.get_scrubbed_data()
21
+
22
+ assert df["text_id"].max() == 10
23
+ assert len(df["text_id"]) == 10
24
+
25
+
26
+ def test_get_scrubbed_data(scrub_object):
27
+ scrub_object.all()
28
+ df = scrub_object.get_scrubbed_data()
29
+
30
+ expected_df = pd.DataFrame(
31
+ {
32
+ "text_id": {0: 1, 1: 2},
33
+ "scrubbed_presidio_person": {0: ["Hamish McDonald", "L. Salah", "Elena Suárez"], 1: None},
34
+ "scrubbed_uk_phone_numbers": {0: None, 1: ["+441111111111"]},
35
+ "scrubbed_uk_postcodes": {0: None, 1: ["AA11 1AA"]},
36
+ }
37
+ )
38
+
39
+ assert_frame_equal(df, expected_df)
test/test_chain.py ADDED
@@ -0,0 +1,54 @@
1
+ import pandas as pd
2
+ from pandas.testing import assert_frame_equal
3
+
4
+
5
+ # Note: These tests will fail if the kernel has not been restarted since the SpaCy model was downloaded.
6
+ def test_chain(scrub_object):
7
+ scrub_object.uk_phone_numbers()
8
+ scrub_object.uk_postcodes()
9
+ scrubbed = scrub_object.spacy_persons()
10
+
11
+ assert scrubbed == [
12
+ "Our names are [PERSON], [PERSON], and [PERSON].",
13
+ "My number is [PHONENO] and I live at [POSTCODE].",
14
+ ]
15
+
16
+
17
+ def test_chain_order(scrub_object):
18
+ scrubbed = scrub_object.uk_phone_numbers()
19
+
20
+ assert scrubbed == [
21
+ "Our names are Hamish McDonald, L. Salah, and Elena Suárez.",
22
+ "My number is [PHONENO] and I live at AA11 1AA.",
23
+ ]
24
+
25
+ assert scrub_object.get_scrubbed_data()["scrubbed_uk_phone_numbers"].to_list() == [["+441111111111"]]
26
+ assert "scrubbed_uk_postcodes" not in scrub_object.get_scrubbed_data().columns
27
+
28
+ scrubbed = scrub_object.uk_postcodes()
29
+
30
+ assert scrubbed == [
31
+ "Our names are Hamish McDonald, L. Salah, and Elena Suárez.",
32
+ "My number is [PHONENO] and I live at [POSTCODE].",
33
+ ]
34
+ assert scrub_object.get_scrubbed_data()["scrubbed_uk_phone_numbers"].to_list() == [["+441111111111"]]
35
+ assert scrub_object.get_scrubbed_data()["scrubbed_uk_postcodes"].to_list() == [["AA11 1AA"]]
36
+
37
+
38
+ def test_get_scrubbed_data_chain(scrub_object):
39
+ scrub_object.uk_phone_numbers()
40
+ scrub_object.uk_postcodes()
41
+ scrub_object.spacy_persons()
42
+
43
+ df = scrub_object.get_scrubbed_data()
44
+
45
+ expected_df = pd.DataFrame(
46
+ {
47
+ "text_id": {0: 1, 1: 2},
48
+ "scrubbed_uk_phone_numbers": {0: None, 1: ["+441111111111"]},
49
+ "scrubbed_uk_postcodes": {0: None, 1: ["AA11 1AA"]},
50
+ "scrubbed_spacy_person": {0: ["Hamish McDonald", "L. Salah", "Elena Suárez"], 1: None},
51
+ }
52
+ )
53
+
54
+ assert_frame_equal(df, expected_df)
test/test_dataframe.py ADDED
@@ -0,0 +1,51 @@
1
+ import pandas as pd
2
+ from idscrub import IDScrub
3
+ from pandas.testing import assert_frame_equal
4
+
5
+
6
+ # Note: These tests will fail if the kernel has not been restarted since the SpaCy model was downloaded.
7
+ def test_dataframe_outputs():
8
+ df = pd.DataFrame(
9
+ {
10
+ "ID": [1, 2],
11
+ "Pride and Prejudice": [
12
+ "Mr. Darcy walked off; and Elizabeth remained with no very cordial feelings toward him.",
13
+ "Mr. Bennet was so odd a mixture of quick parts, sarcastic humour, reserve, and caprice.",
14
+ ],
15
+ "Fake book": [
16
+ "The letter to freddie-mercury@queen.com was stamped with SW1A 2AA.",
17
+ "She forwarded the memo from Mick Jagger and David Bowie to her chief of staff, noting the postcode SW1A 2WH.",
18
+ ],
19
+ }
20
+ )
21
+
22
+ scrubbed_df, scrubbed_data = IDScrub.dataframe(df=df, id_col="ID", scrub_methods=["all"])
23
+
24
+ expected_scrubbed_df = pd.DataFrame(
25
+ {
26
+ "ID": [1, 2],
27
+ "Pride and Prejudice": [
28
+ "[TITLE]. [PERSON] walked off; and [PERSON] remained with no very cordial feelings toward him.",
29
+ "[TITLE]. [PERSON] was so odd a mixture of quick parts, sarcastic humour, reserve, and caprice.",
30
+ ],
31
+ "Fake book": [
32
+ "The letter to [EMAIL_ADDRESS] was stamped with [POSTCODE].",
33
+ "She forwarded the memo from [PERSON] and [PERSON] to her chief of staff, noting the postcode [POSTCODE].",
34
+ ],
35
+ }
36
+ )
37
+
38
+ expected_scrubbed_data = pd.DataFrame(
39
+ {
40
+ "ID": [1, 2, 1, 2],
41
+ "column": ["Pride and Prejudice", "Pride and Prejudice", "Fake book", "Fake book"],
42
+ "scrubbed_presidio_person": [["Darcy", "Elizabeth"], ["Bennet"], None, ["Mick Jagger", "David Bowie"]],
43
+ "scrubbed_titles": [["Mr"], ["Mr"], None, None],
44
+ "scrubbed_presidio_email_address": [None, None, ["freddie-mercury@queen.com"], None],
45
+ "scrubbed_presidio_url": [None, None, ["queen.com"], None],
46
+ "scrubbed_uk_postcodes": [None, None, ["SW1A 2AA"], ["SW1A 2WH"]],
47
+ }
48
+ )
49
+
50
+ assert_frame_equal(scrubbed_df, expected_scrubbed_df)
51
+ assert_frame_equal(scrubbed_data, expected_scrubbed_data)
@@ -0,0 +1,25 @@
1
+ import pandas as pd
2
+ import pytest
3
+ from idscrub import IDScrub
4
+ from pandas.testing import assert_frame_equal
5
+
6
+
7
+ def test_huggingface():
8
+ scrub = IDScrub(texts=["Our names are Hamish McDonald, L. Salah, and Elena Suárez."])
9
+ scrubbed = scrub.huggingface_persons()
10
+ assert scrubbed == ["Our names are [PERSON], [PERSON], and [PERSON]."]
11
+
12
+
13
+ def test_huggingface_error():
14
+ scrub = IDScrub(texts=["Our names are Hamish McDonald, L. Salah, and Elena Suárez."])
15
+
16
+ with pytest.raises(OSError):
17
+ scrub.huggingface_persons(hf_model_path="not_a_path")
18
+
19
+
20
+ def test_huggingface_empty():
21
+ scrub = IDScrub([" ", "John Smith", ""])
22
+ scrubbed = scrub.huggingface_persons()
23
+
24
+ assert scrubbed == [" ", "[PERSON]", ""]
25
+ assert_frame_equal(scrub.get_scrubbed_data(), pd.DataFrame({"text_id": 2, "scrubbed_hf_person": [["John Smith"]]}))
test/test_id.py ADDED
@@ -0,0 +1,24 @@
1
+ from idscrub import IDScrub
2
+
3
+
4
+ def test_id_ints():
5
+ scrub = IDScrub(texts=["clement_attlee@gmail.com"] * 10, text_ids=range(100, 110), text_id_name="PM")
6
+ scrub.email_addresses()
7
+ assert scrub.get_scrubbed_data()["PM"].min() == 100
8
+ assert scrub.get_scrubbed_data()["PM"].max() == 109
9
+ assert scrub.get_scrubbed_data()["PM"].to_list() == [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
10
+
11
+
12
+ def test_id_strs():
13
+ scrub = IDScrub(texts=["clement_attlee@gmail.com"] * 2, text_ids=["random", "minister"], text_id_name="PM")
14
+ scrub.email_addresses()
15
+ assert scrub.get_scrubbed_data()["PM"][0] == "random"
16
+ assert scrub.get_scrubbed_data()["PM"][1] == "minister"
17
+
18
+
19
+ def test_multiple():
20
+ scrub = IDScrub(texts=["clement_attlee@gmail.com", "SW1A 2AA"] * 10, text_ids=range(100, 120), text_id_name="PM")
21
+ scrub.email_addresses()
22
+ scrub.uk_postcodes()
23
+ assert scrub.get_scrubbed_data()["PM"].min() == 100
24
+ assert scrub.get_scrubbed_data()["PM"].max() == 119
test/test_log.py ADDED
@@ -0,0 +1,17 @@
1
+ from idscrub import IDScrub
2
+
3
+
4
+ def test_log_message():
5
+ scrub = IDScrub(texts=["My name is Dr Strangelove. Dr. Strangelove is my name", "My name is Professor Oppenheimer"])
6
+ scrub.titles()
7
+ count = scrub.log_message("scrubbed_titles")
8
+ assert count == 3
9
+
10
+
11
+ def test_log_message_custom_regex():
12
+ scrub = IDScrub(texts=["My name is Dr Strangelove. Dr. Strangelove is my name", "My name is Professor Oppenheimer"])
13
+ scrub.custom_regex([r"Strangelove", r"Oppenheimer"], ["[DR]", "[PROFESSOR]"])
14
+ count_1 = scrub.log_message("scrubbed_custom_regex_1")
15
+ count_2 = scrub.log_message("scrubbed_custom_regex_2")
16
+ assert count_1 == 2
17
+ assert count_2 == 1
test/test_persidio.py ADDED
@@ -0,0 +1,44 @@
1
+ import pandas as pd
2
+ from idscrub import IDScrub
3
+ from pandas.testing import assert_frame_equal
4
+
5
+
6
+ # Note: These tests will fail if the kernel has not been restarted since the SpaCy model was downloaded.
7
+ def test_persidio():
8
+ scrub = IDScrub(
9
+ ["Our names are Hamish McDonald, L. Salah, and Elena Suárez.", "My IBAN code is GB91BKEN10000041610008."]
10
+ )
11
+ scrubbed_texts = scrub.presidio(entities_to_scrub=["PERSON", "IBAN_CODE"])
12
+
13
+ assert scrubbed_texts == ["Our names are [PERSON], [PERSON], and [PERSON].", "My IBAN code is [IBAN_CODE]."]
14
+
15
+
16
+ def test_persidio_map():
17
+ scrub = IDScrub(
18
+ ["Our names are Hamish McDonald, L. Salah, and Elena Suárez.", "My IBAN code is GB91BKEN10000041610008."]
19
+ )
20
+ scrubbed_texts = scrub.presidio(
21
+ entities_to_scrub=["PERSON", "IBAN_CODE"], replacement_map={"PERSON": "[PHELLO]", "IBAN_CODE": "[IHELLO]"}
22
+ )
23
+
24
+ assert scrubbed_texts == ["Our names are [PHELLO], [PHELLO], and [PHELLO].", "My IBAN code is [IHELLO]."]
25
+
26
+
27
+ def test_persidio_get_data():
28
+ scrub = IDScrub(
29
+ ["Our names are Hamish McDonald, L. Salah, and Elena Suárez.", "My IBAN code is GB91BKEN10000041610008."]
30
+ )
31
+
32
+ scrub.presidio(entities_to_scrub=["PERSON", "IBAN_CODE"])
33
+
34
+ df = scrub.get_scrubbed_data()
35
+
36
+ expected_df = pd.DataFrame(
37
+ {
38
+ "text_id": {0: 1, 1: 2},
39
+ "scrubbed_presidio_person": {0: ["Hamish McDonald", "L. Salah", "Elena Suárez"], 1: None},
40
+ "scrubbed_presidio_iban_code": {0: None, 1: ["GB91BKEN10000041610008"]},
41
+ }
42
+ )
43
+
44
+ assert_frame_equal(df, expected_df)
@@ -0,0 +1,13 @@
1
+ from idscrub import IDScrub
2
+
3
+
4
+ def test_google_phone_numbers_gb():
5
+ scrub = IDScrub(texts=["My phone number is +441234567891! My old phone number is 01475 123456."])
6
+ scrubbed = scrub.google_phone_numbers(region="GB")
7
+ assert scrubbed == ["My phone number is [PHONENO]! My old phone number is [PHONENO]."]
8
+
9
+
10
+ def test_google_phone_numbers_us():
11
+ scrub = IDScrub(texts=["My US phone number is +1-718-222-2222! My old phone number is 12124567890."])
12
+ scrubbed = scrub.google_phone_numbers(region="US")
13
+ assert scrubbed == ["My US phone number is [PHONENO]! My old phone number is [PHONENO]."]
test/test_regex.py ADDED
@@ -0,0 +1,123 @@
1
+ import re
2
+
3
+ from idscrub import IDScrub
4
+
5
+
6
+ def test_email_addresses():
7
+ scrub = IDScrub(
8
+ texts=["Send me an email at jim@gmail.com or at marie-9999@randomemail.co.uk or at hello_world@john-smith.com."]
9
+ )
10
+ scrubbed = scrub.email_addresses()
11
+ assert scrubbed == ["Send me an email at [EMAIL_ADDRESS] or at [EMAIL_ADDRESS] or at [EMAIL_ADDRESS]."]
12
+
13
+
14
+ def test_ip_addresses():
15
+ scrub = IDScrub(texts=["This has been sent to 8.8.8.8 and requested by 192.0.2.1."])
16
+ scrubbed = scrub.ip_addresses()
17
+ assert scrubbed == ["This has been sent to [IPADDRESS] and requested by [IPADDRESS]."]
18
+
19
+
20
+ def test_uk_postcodes():
21
+ scrub = IDScrub(texts=["I live at A11 1AA. My friend lives at KA308JB. The Prime Minister lives at SW1A 2AA."])
22
+ scrubbed = scrub.uk_postcodes()
23
+ assert scrubbed == ["I live at [POSTCODE]. My friend lives at [POSTCODE]. The Prime Minister lives at [POSTCODE]."]
24
+
25
+
26
+ def test_titles_not_strict():
27
+ scrub = IDScrub(
28
+ texts=[
29
+ "Hello Dr. Smith! I am Mrs Patel",
30
+ "I am here on behalf of Ms Austen, General Eisenhower, and Captain Jack Sparrow.",
31
+ ]
32
+ )
33
+ scrubbed = scrub.titles()
34
+ assert scrubbed == [
35
+ "Hello [TITLE]. Smith! I am [TITLE] Patel",
36
+ "I am here on behalf of [TITLE] Austen, General Eisenhower, and [TITLE] Jack Sparrow.",
37
+ ]
38
+
39
+
40
+ def test_titles_strict():
41
+ scrub = IDScrub(
42
+ texts=[
43
+ "Hello Dr. Smith! I am Mrs Patel",
44
+ "I am here on behalf of Ms Austen, General Eisenhower, and Captain Jack Sparrow.",
45
+ ]
46
+ )
47
+ scrubbed = scrub.titles(strict=True)
48
+ assert scrubbed == [
49
+ "Hello [TITLE]. Smith! I am [TITLE] Patel",
50
+ "I am here on behalf of [TITLE] Austen, [TITLE] Eisenhower, and [TITLE] Jack Sparrow.",
51
+ ]
52
+
53
+
54
+ def test_uk_phone_numbers():
55
+ scrub = IDScrub(texts=["My phone number is +441234567891! My old phone number is 01111 123456."])
56
+ scrubbed = scrub.uk_phone_numbers()
57
+ assert scrubbed == ["My phone number is [PHONENO]! My old phone number is [PHONENO]."]
58
+
59
+
60
+ def test_handles():
61
+ scrub = IDScrub(texts=["Our usernames are @HenrikLarsson, @Jimmy_Johnstone, @Nakamura-67 and @Aidan_McGeady_46."])
62
+ scrubbed = scrub.handles()
63
+ assert scrubbed == ["Our usernames are [HANDLE], [HANDLE], [HANDLE] and [HANDLE]."]
64
+
65
+
66
+ def test_claimants():
67
+ scrub = IDScrub(
68
+ texts=[
69
+ "This is legal text. Claimant: John Smith Respondents: Jill Hill.",
70
+ "Claimant: J Smith Respondents: Jill Hill. J Smith is the respondent.",
71
+ ]
72
+ )
73
+ scrubbed = scrub.claimants()
74
+ assert scrubbed == [
75
+ "This is legal text. Claimant: [CLAIMANT] Respondents: Jill Hill.",
76
+ "Claimant: [CLAIMANT] Respondents: Jill Hill. [CLAIMANT] is the respondent.",
77
+ ]
78
+
79
+
80
+ def test_custom_regex():
81
+ scrub = IDScrub(texts=["It was the best of times, it was the worst of times"])
82
+ scrubbed = scrub.custom_regex(custom_regex_patterns=[r"times"])
83
+ assert scrubbed == ["It was the best of [REDACTED], it was the worst of [REDACTED]"]
84
+
85
+ scrub = IDScrub(texts=["It was the best of times, it was the worst of times"])
86
+ scrubbed = scrub.custom_regex(
87
+ custom_regex_patterns=[r"times", "worst"], custom_replacement_texts=["[DICKENS]", "[WORST]"]
88
+ )
89
+ assert scrubbed == ["It was the best of [DICKENS], it was the [WORST] of [DICKENS]"]
90
+
91
+
92
+ def test_scrub_and_collect():
93
+ scrub = IDScrub()
94
+ text = "Hello Muhammad and Jack."
95
+ pattern = r"\bMuhammad|Jack\b"
96
+ replacement = "[NAME]"
97
+ removed_label = "scrubbed_custom_regex"
98
+ i = 1
99
+
100
+ def replacer(match):
101
+ return scrub.scrub_and_collect(match, text, replacement, i, removed_label)
102
+
103
+ scrubbed = re.sub(pattern, replacer, text)
104
+
105
+ assert scrubbed == "Hello [NAME] and [NAME]."
106
+ assert scrub.scrubbed_data == [
107
+ {"text_id": 1, "scrubbed_custom_regex": "Muhammad"},
108
+ {"text_id": 1, "scrubbed_custom_regex": "Jack"},
109
+ ]
110
+
111
+
112
+ def test_remove_regex():
113
+ scrub = IDScrub(texts=["Hi! My name is Clement Atlee!", "I am Harold Wilson."])
114
+ removed_label = "scrubbed_regex_names"
115
+ pattern = r"Clement Atlee|Harold Wilson"
116
+ replacement_text = "[PM]"
117
+ scrubbed = scrub.scrub_regex(pattern, replacement_text, removed_label)
118
+
119
+ assert scrubbed == ["Hi! My name is [PM]!", "I am [PM]."]
120
+ assert scrub.scrubbed_data == [
121
+ {"text_id": 1, "scrubbed_regex_names": "Clement Atlee"},
122
+ {"text_id": 2, "scrubbed_regex_names": "Harold Wilson"},
123
+ ]
test/test_spacy.py ADDED
@@ -0,0 +1,28 @@
1
+ import pandas as pd
2
+ import pytest
3
+ from idscrub import IDScrub
4
+ from pandas.testing import assert_frame_equal
5
+
6
+
7
+ # Note: This test will fail if the kernel has not been restarted since the SpaCy model was downloaded.
8
+ def test_spacy():
9
+ scrub = IDScrub(texts=["Our names are Hamish McDonald, L. Salah, and Elena Suárez."])
10
+ scrubbed = scrub.spacy_persons(model_name="en_core_web_trf")
11
+ assert scrubbed == ["Our names are [PERSON], [PERSON], and [PERSON]."]
12
+
13
+
14
+ def test_spacy_error():
15
+ scrub = IDScrub(texts=["Our names are Hamish McDonald, L. Salah, and Elena Suárez."])
16
+
17
+ with pytest.raises(ValueError):
18
+ scrub.spacy_persons(model_name="not_a_model")
19
+
20
+
21
+ def test_spacy_empty():
22
+ scrub = IDScrub([" ", "John Smith", ""])
23
+ scrubbed = scrub.spacy_persons()
24
+
25
+ assert scrubbed == [" ", "[PERSON]", ""]
26
+ assert_frame_equal(
27
+ scrub.get_scrubbed_data(), pd.DataFrame({"text_id": 2, "scrubbed_spacy_person": [["John Smith"]]})
28
+ )