idscrub 0.2.0__py3-none-any.whl → 0.2.2__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.
idscrub/scrub.py CHANGED
@@ -906,11 +906,8 @@ class IDScrub:
906
906
 
907
907
  """
908
908
 
909
- for i, scrub_method in enumerate(scrub_methods):
910
- if i == len(scrub_methods) - 1:
911
- self.call_scrub_method(scrub_method)
912
- else:
913
- self.call_scrub_method(scrub_method)
909
+ for scrub_method in scrub_methods:
910
+ self.call_scrub_method(scrub_method)
914
911
 
915
912
  return self.cleaned_texts
916
913
 
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idscrub
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Author: Department for Business and Trade
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
7
  License-File: LICENSE
8
8
  Requires-Dist: ipykernel>=7.1.0
9
+ Requires-Dist: ipywidgets
9
10
  Requires-Dist: numpy>=2.3.4
10
11
  Requires-Dist: pandas>=2.3.3
11
12
  Requires-Dist: phonenumbers>=9.0.18
@@ -20,36 +21,45 @@ Dynamic: license-file
20
21
 
21
22
  # idscrub 🧽✨
22
23
 
23
- ## Project Information
24
+ * Names and other personally identifying information are often present in text.
25
+ * This information may need to be removed prior to further analysis in many cases.
26
+ * `idscrub` identifies and removes (*✨scrubs✨*) personal data from text using [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) and [named-entity recognition](https://en.wikipedia.org/wiki/Named-entity_recognition).
24
27
 
25
- * This package removes (*✨scrubs✨*) identifying personal data from text using [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) and [named-entity recognition](https://en.wikipedia.org/wiki/Named-entity_recognition).
28
+ ## Installation
26
29
 
27
- > [!WARNING]
28
- > You must follow [GDPR guidance](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/the-research-provisions/principles-and-grounds-for-processing/) when processing personal data using this package.
29
- >
30
- > Specifically, you must:
31
- >
32
- > - **Update privacy notices**: Clearly state this processing activity in new or existing privacy notices before using the package.
33
- > - **Ensure secure deletion**: Remove any temporary or intermediary files and outputs in a secure manner.
34
- > - **Ensure data subject rights upheld**: Ensure individuals can access, correct, or erase their data as required.
35
- > - **Maintain processing records**: Document how personal data is handled and for what purpose.
30
+ `idscrub` can be installed using `pip` into a Python **>=3.12** environment. Example:
36
31
 
37
- ### Description
32
+ ```console
33
+ pip install idscrub
34
+ ```
35
+ or with the spaCy transformer model (`en_core_web_trf`) already installed:
38
36
 
39
- * Names and other personally identifying information are often present in text.
40
- * This information may need to be removed prior to further analysis in many cases.
41
- * `idscrub` provides a standardised way to do this in the Department for Business and Trade.
37
+ ```console
38
+ pip install idscrub[trf]
39
+ ```
40
+ ## How to use the code
42
41
 
43
- ### Expected Outputs
42
+ Basic usage example (see [basic_usage.ipynb](https://github.com/uktrade/idscrub/blob/main/notebooks/basic_usage.ipynb) for further examples):
44
43
 
45
- * A list of text with names and other identifying information removed.
44
+ ```python
45
+ from idscrub import IDScrub
46
46
 
47
- > [!WARNING]
48
- > * This package has been designed as a *first pass* for standardised personal data removal.
49
- > * Users are encouraged to check and confirm outputs and conduct manual reviews where necessary, e.g. when cleaning high risk datasets.
50
- > * It is up to the user to assess whether this removal process needs to be supplemented by other methods for their given dataset and security requirements.
47
+ scrub = IDScrub(['Our names are Hamish McDonald, L. Salah, and Elena Suárez.', 'My number is +441111111111 and I live at AA11 1AA.'])x
48
+ scrubbed_texts = scrub.scrub(scrub_methods=['spacy_persons', 'uk_phone_numbers', 'uk_postcodes'])
51
49
 
52
- ### Data
50
+ print(scrubbed_texts)
51
+
52
+ # Output: ['Our names are [PERSON], [PERSON], and [PERSON].', 'My number is [PHONENO] and I live at [POSTCODE].']
53
+ ```
54
+
55
+ ## Considerations before use
56
+
57
+ - You must follow [GDPR guidance](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/the-research-provisions/principles-and-grounds-for-processing/) when processing personal data using this package.
58
+ - This package has been designed as a *first pass* for standardised personal data removal.
59
+ - Users are encouraged to check and confirm outputs and conduct manual reviews where necessary, e.g. when cleaning high risk datasets.
60
+ - It is up to the user to assess whether this removal process needs to be supplemented by other methods for their given dataset and security requirements.
61
+
62
+ ### Input data
53
63
 
54
64
  - This package is designed for text-based documents structured as a list of strings.
55
65
  - It performs best when contextual meaning can be inferred from the text.
@@ -67,50 +77,25 @@ Dynamic: license-file
67
77
  > [!IMPORTANT]
68
78
  > * See [our wiki](https://github.com/uktrade/idscrub/wiki/Evaluation) for further details and notes on our evaluation of `idscrub`.
69
79
 
70
- ### Models and Memory
80
+ ### Models
71
81
 
72
82
  * Only Spacy's `en_core_web_trf` and no Hugging Face models have been formally evaluated.
73
83
  * We therefore recommend that the current default `en_core_web_trf` is used for name scrubbing. **Other models need to be evaluated by the user.**
74
84
 
75
- > [!IMPORTANT]
76
- > Spacy and Hugging Face models have high memory requirements. To avoid memory-related errors. Clear the auto-generated `huggingface` folder if not in use. Do not push the `huggingface` folder (or user-defined equivalent) to GitHub.
77
-
78
85
  ## Similar Python packages
79
86
 
80
- * Similar packages exist for undertaking this task, such as [presidio](https://microsoft.github.io/presidio/), [scrubadub](https://github.com/LeapBeyond/scrubadub) and [sanityze](https://github.com/UBC-MDS/sanityze).
81
- * Development of `idscrub` was undertaken to: bring together different scrubbing methods across the department, adhere to infrastructure requirements, guarantee future stability and maintainability, and encourage future scrubbing methods to be added collaboratively and transparently.
82
- * To leverage the power of other packages, we have added methods that allow you to interact with them. These include: `IDScrub.presidio()` and `IDScrub.google_phone_numbers()`. See the [usage example notebook](https://github.com/uktrade/idscrub/blob/main/notebooks/basic_usage.ipynb) and method docstrings for further information.
83
-
84
-
85
- ## Installation
86
-
87
- `idscrub` can be installed using `pip` into a Python **>=3.12** environment. Example:
88
-
89
- ```console
90
- pip install idscrub
91
- ```
92
- or with the spaCy transformer model (`en_core_web_trf`) already installed:
93
-
94
- ```console
95
- pip instll idscrub[trf]
96
- ```
97
-
98
- ## How to use the code
99
-
100
- Basic usage example (see `notebooks/basic_usage.ipynb` for further examples):
87
+ * Similar packages exist for undertaking this task, such as [Presidio](https://microsoft.github.io/presidio/), [Scrubadub](https://github.com/LeapBeyond/scrubadub) and [Sanityze](https://github.com/UBC-MDS/sanityze).
88
+ * Development of `idscrub` was undertaken to:
101
89
 
102
- ```python
103
- from idscrub import IDScrub
104
-
105
- scrub = IDScrub(['Our names are Hamish McDonald, L. Salah, and Elena Suárez.', 'My number is +441111111111 and I live at AA11 1AA.'])
106
- scrubbed_texts = scrub.scrub(scrub_methods=['spacy_persons', 'uk_phone_numbers', 'uk_postcodes'])
107
-
108
- print(scrubbed_texts)
109
-
110
- # Output: ['Our names are [PERSON], [PERSON], and [PERSON].', 'My number is [PHONENO] and I live at [POSTCODE].']
111
- ```
90
+ * Bring together different scrubbing methods across the Department for Business and Trade.
91
+ * Adhere to infrastructure requirements.
92
+ * Guarantee future stability and maintainability.
93
+ * Encourage future scrubbing methods to be added collaboratively and transparently.
94
+ * Allow for full flexibility depending on the use case and required outputs.
95
+
96
+ * To leverage the power of other packages, we have added methods that allow you to interact with them. These include: `IDScrub.presidio()` and `IDScrub.google_phone_numbers()`. See the [usage example notebook](https://github.com/uktrade/idscrub/blob/main/notebooks/basic_usage.ipynb) and method docstrings for further information.
112
97
 
113
- ## AI Declaration
98
+ ## AI declaration
114
99
 
115
100
  AI has been used in the development of `idscrub`, primarily to develop regular expressions, suggest code refinements and draft documentation.
116
101
 
@@ -1,8 +1,8 @@
1
1
  idscrub/__init__.py,sha256=cRugJv27q1q--bl-VNLpfiScJb_ROlUxyLFhaF55S1w,38
2
2
  idscrub/locations.py,sha256=7fMNOcGMYe7sX8TrfhMW6oYGAlc1WVYVQKQbpxE3pqo,217
3
- idscrub/scrub.py,sha256=cYA76efkbR6rjHvl9yejtwmJ6MV8qx7_V4Azk4sWhjA,35073
4
- idscrub-0.2.0.dist-info/licenses/LICENSE,sha256=JJnuf10NSx7YXglte1oH_N9ZP3AcWR_Y8irvQb_wnsg,1090
5
- notebooks/basic_usage.ipynb,sha256=2fQdapXAFb79ZTcMfveqSC4TMNrsvqDpvF15rw3LUvM,39798
3
+ idscrub/scrub.py,sha256=K4Sw4DxKhYJnnu_vpRhUcqj-AbeGr8SwDB0XrDLEciM,34940
4
+ idscrub-0.2.2.dist-info/licenses/LICENSE,sha256=JJnuf10NSx7YXglte1oH_N9ZP3AcWR_Y8irvQb_wnsg,1090
5
+ notebooks/basic_usage.ipynb,sha256=eQFU3mOyRXbCwFz3jVUKCxWRtIP5Jptny8fj-KYoBwA,39784
6
6
  test/conftest.py,sha256=ph1S3LMvzlzvOsb3l2YhpyHSdmg4uV7p61ge_JVCGv0,267
7
7
  test/test_all.py,sha256=z6v9O2Ts9dWITlhvZwRMyKUZsO7ncaT3znqqBCKJ6Wc,1141
8
8
  test/test_chain.py,sha256=YFGqO0xUzZ69x-iNCdKEiH-OWWZfyYYFgmEq0urELEs,1883
@@ -15,7 +15,7 @@ test/test_phonenumbers.py,sha256=hZsXgwhn5R-7426TTWwCH9gWQwhyHtjLUstN10jnX6c,607
15
15
  test/test_regex.py,sha256=EQGx3PHwJJzIdy6xwR8gEsSRDtlWHR-U81EPI811eZA,4474
16
16
  test/test_scrub.py,sha256=pohmw3frtlkmZDMvOEbmvVJgtcVdFlEDL3TxR5-y-0Q,1422
17
17
  test/test_spacy.py,sha256=mrUGUulvzDGgQRttdG0tgL2sGBRmYfg1fDNp7SFq8as,961
18
- idscrub-0.2.0.dist-info/METADATA,sha256=2NERZcMHsGbnotclunZ-0ZgZaCMAN39j9s_zswp1bXQ,6101
19
- idscrub-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- idscrub-0.2.0.dist-info/top_level.txt,sha256=D4EEodXGCjGiX35ObiBTmjjBAdouN-eCvH-LezGGtks,23
21
- idscrub-0.2.0.dist-info/RECORD,,
18
+ idscrub-0.2.2.dist-info/METADATA,sha256=IHoFTVY6cJARkeeKoQlpunA7Nboc4y32bpSoS-IgSoM,5352
19
+ idscrub-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ idscrub-0.2.2.dist-info/top_level.txt,sha256=D4EEodXGCjGiX35ObiBTmjjBAdouN-eCvH-LezGGtks,23
21
+ idscrub-0.2.2.dist-info/RECORD,,
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "cell_type": "code",
12
- "execution_count": 12,
12
+ "execution_count": 1,
13
13
  "metadata": {},
14
14
  "outputs": [
15
15
  {
@@ -18,7 +18,7 @@
18
18
  "text": [
19
19
  "INFO: Texts loaded.\n",
20
20
  "INFO: Scrubbing names using SpaCy model `en_core_web_trf`...\n",
21
- "100%|██████████| 2/2 [00:00<00:00, 44.29it/s]\n",
21
+ "100%|██████████| 2/2 [00:00<00:00, 28.72it/s]\n",
22
22
  "INFO: 3 spacy person scrubbed.\n",
23
23
  "INFO: Scrubbing phone numbers using regex...\n",
24
24
  "INFO: 1 uk phone numbers scrubbed.\n",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  {
53
53
  "cell_type": "code",
54
- "execution_count": 13,
54
+ "execution_count": 2,
55
55
  "metadata": {},
56
56
  "outputs": [
57
57
  {
@@ -110,7 +110,7 @@
110
110
  "1 [+441111111111] [AA11 1AA] "
111
111
  ]
112
112
  },
113
- "execution_count": 13,
113
+ "execution_count": 2,
114
114
  "metadata": {},
115
115
  "output_type": "execute_result"
116
116
  }
@@ -128,7 +128,7 @@
128
128
  },
129
129
  {
130
130
  "cell_type": "code",
131
- "execution_count": 14,
131
+ "execution_count": 3,
132
132
  "metadata": {},
133
133
  "outputs": [
134
134
  {
@@ -137,11 +137,11 @@
137
137
  "text": [
138
138
  "INFO: Texts loaded.\n",
139
139
  "INFO: Scrubbing using Presidio...\n",
140
- "100%|██████████| 2/2 [00:00<00:00, 25.19it/s]\n",
140
+ "100%|██████████| 2/2 [00:00<00:00, 14.92it/s]\n",
141
141
  "INFO: 3 presidio person scrubbed.\n",
142
142
  "INFO: 1 presidio location scrubbed.\n",
143
143
  "INFO: Scrubbing names using SpaCy model `en_core_web_trf`...\n",
144
- "100%|██████████| 2/2 [00:00<00:00, 48.66it/s]\n",
144
+ "100%|██████████| 2/2 [00:00<00:00, 49.69it/s]\n",
145
145
  "INFO: 0 spacy person scrubbed.\n",
146
146
  "INFO: Scrubbing GB phone numbers using Google's `phonenumbers`...\n",
147
147
  "INFO: 0 gb phone numbers scrubbed.\n",
@@ -184,7 +184,7 @@
184
184
  },
185
185
  {
186
186
  "cell_type": "code",
187
- "execution_count": 15,
187
+ "execution_count": 4,
188
188
  "metadata": {},
189
189
  "outputs": [
190
190
  {
@@ -246,7 +246,7 @@
246
246
  "1 [Lapland] [+441111111111] [AA11 1AA] "
247
247
  ]
248
248
  },
249
- "execution_count": 15,
249
+ "execution_count": 4,
250
250
  "metadata": {},
251
251
  "output_type": "execute_result"
252
252
  }
@@ -264,7 +264,7 @@
264
264
  },
265
265
  {
266
266
  "cell_type": "code",
267
- "execution_count": 16,
267
+ "execution_count": 5,
268
268
  "metadata": {},
269
269
  "outputs": [
270
270
  {
@@ -273,7 +273,7 @@
273
273
  "text": [
274
274
  "INFO: Texts loaded.\n",
275
275
  "INFO: Scrubbing using Presidio...\n",
276
- "100%|██████████| 2/2 [00:00<00:00, 23.03it/s]\n",
276
+ "100%|██████████| 2/2 [00:00<00:00, 29.00it/s]\n",
277
277
  "INFO: 3 presidio person scrubbed.\n",
278
278
  "INFO: Scrubbing GB phone numbers using Google's `phonenumbers`...\n",
279
279
  "INFO: 0 gb phone numbers scrubbed.\n",
@@ -324,7 +324,7 @@
324
324
  },
325
325
  {
326
326
  "cell_type": "code",
327
- "execution_count": 17,
327
+ "execution_count": 6,
328
328
  "metadata": {},
329
329
  "outputs": [
330
330
  {
@@ -389,7 +389,7 @@
389
389
  "1 [ACHILLES] [+441111111111] [AA11 1AA] "
390
390
  ]
391
391
  },
392
- "execution_count": 17,
392
+ "execution_count": 6,
393
393
  "metadata": {},
394
394
  "output_type": "execute_result"
395
395
  }
@@ -408,7 +408,7 @@
408
408
  },
409
409
  {
410
410
  "cell_type": "code",
411
- "execution_count": 18,
411
+ "execution_count": 7,
412
412
  "metadata": {},
413
413
  "outputs": [
414
414
  {
@@ -417,7 +417,7 @@
417
417
  "text": [
418
418
  "INFO: Texts loaded.\n",
419
419
  "INFO: Scrubbing using Presidio...\n",
420
- "100%|██████████| 2/2 [00:00<00:00, 23.38it/s]\n",
420
+ "100%|██████████| 2/2 [00:00<00:00, 24.48it/s]\n",
421
421
  "INFO: 3 presidio person scrubbed.\n",
422
422
  "INFO: 1 presidio iban code scrubbed.\n"
423
423
  ]
@@ -443,7 +443,7 @@
443
443
  },
444
444
  {
445
445
  "cell_type": "code",
446
- "execution_count": 19,
446
+ "execution_count": 8,
447
447
  "metadata": {},
448
448
  "outputs": [
449
449
  {
@@ -499,7 +499,7 @@
499
499
  "1 [GB91BKEN10000041610008] "
500
500
  ]
501
501
  },
502
- "execution_count": 19,
502
+ "execution_count": 8,
503
503
  "metadata": {},
504
504
  "output_type": "execute_result"
505
505
  }
@@ -517,7 +517,7 @@
517
517
  },
518
518
  {
519
519
  "cell_type": "code",
520
- "execution_count": 20,
520
+ "execution_count": 9,
521
521
  "metadata": {},
522
522
  "outputs": [
523
523
  {
@@ -623,7 +623,7 @@
623
623
  "4 They did not expected a reply from otis.reddin... "
624
624
  ]
625
625
  },
626
- "execution_count": 20,
626
+ "execution_count": 9,
627
627
  "metadata": {},
628
628
  "output_type": "execute_result"
629
629
  }
@@ -669,7 +669,7 @@
669
669
  },
670
670
  {
671
671
  "cell_type": "code",
672
- "execution_count": 21,
672
+ "execution_count": 10,
673
673
  "metadata": {},
674
674
  "outputs": [
675
675
  {
@@ -678,12 +678,12 @@
678
678
  "text": [
679
679
  " 0%| | 0/3 [00:00<?, ?it/s]INFO: Texts loaded.\n",
680
680
  "INFO: Scrubbing using Presidio...\n",
681
- "100%|██████████| 5/5 [00:00<00:00, 18.99it/s]\n",
681
+ "100%|██████████| 5/5 [00:00<00:00, 31.94it/s]\n",
682
682
  "INFO: 4 presidio person scrubbed.\n",
683
683
  "INFO: 4 presidio person scrubbed.\n",
684
684
  "INFO: 4 presidio person scrubbed.\n",
685
685
  "INFO: Scrubbing names using SpaCy model `en_core_web_trf`...\n",
686
- "100%|██████████| 5/5 [00:00<00:00, 67.00it/s]\n",
686
+ "100%|██████████| 5/5 [00:00<00:00, 71.88it/s]\n",
687
687
  "INFO: 0 spacy person scrubbed.\n",
688
688
  "INFO: Scrubbing GB phone numbers using Google's `phonenumbers`...\n",
689
689
  "INFO: 0 gb phone numbers scrubbed.\n",
@@ -699,13 +699,13 @@
699
699
  "INFO: 0 uk postcodes scrubbed.\n",
700
700
  "INFO: Scrubbing titles using regex...\n",
701
701
  "INFO: 2 titles scrubbed.\n",
702
- " 33%|███▎ | 1/3 [00:03<00:06, 3.24s/it]INFO: Texts loaded.\n",
702
+ " 33%|███▎ | 1/3 [00:02<00:05, 2.55s/it]INFO: Texts loaded.\n",
703
703
  "INFO: Scrubbing using Presidio...\n",
704
- "100%|██████████| 5/5 [00:00<00:00, 21.83it/s]\n",
704
+ "100%|██████████| 5/5 [00:00<00:00, 24.67it/s]\n",
705
705
  "INFO: 2 presidio person scrubbed.\n",
706
706
  "INFO: 2 presidio person scrubbed.\n",
707
707
  "INFO: Scrubbing names using SpaCy model `en_core_web_trf`...\n",
708
- "100%|██████████| 5/5 [00:00<00:00, 84.69it/s]\n",
708
+ "100%|██████████| 5/5 [00:00<00:00, 86.96it/s]\n",
709
709
  "INFO: 0 spacy person scrubbed.\n",
710
710
  "INFO: Scrubbing GB phone numbers using Google's `phonenumbers`...\n",
711
711
  "INFO: 0 gb phone numbers scrubbed.\n",
@@ -721,15 +721,15 @@
721
721
  "INFO: 0 uk postcodes scrubbed.\n",
722
722
  "INFO: Scrubbing titles using regex...\n",
723
723
  "INFO: 0 titles scrubbed.\n",
724
- " 67%|██████▋ | 2/3 [00:06<00:03, 3.24s/it]INFO: Texts loaded.\n",
724
+ " 67%|██████▋ | 2/3 [00:04<00:02, 2.39s/it]INFO: Texts loaded.\n",
725
725
  "INFO: Scrubbing using Presidio...\n",
726
- "100%|██████████| 5/5 [00:00<00:00, 29.32it/s]\n",
726
+ "100%|██████████| 5/5 [00:00<00:00, 15.41it/s]\n",
727
727
  "INFO: 5 presidio url scrubbed.\n",
728
728
  "INFO: 2 presidio person scrubbed.\n",
729
729
  "INFO: 3 presidio email address scrubbed.\n",
730
730
  "INFO: 3 presidio email address scrubbed.\n",
731
731
  "INFO: Scrubbing names using SpaCy model `en_core_web_trf`...\n",
732
- "100%|██████████| 5/5 [00:00<00:00, 66.37it/s]\n",
732
+ "100%|██████████| 5/5 [00:00<00:00, 64.25it/s]\n",
733
733
  "INFO: 0 spacy person scrubbed.\n",
734
734
  "INFO: Scrubbing GB phone numbers using Google's `phonenumbers`...\n",
735
735
  "INFO: 0 gb phone numbers scrubbed.\n",
@@ -745,7 +745,7 @@
745
745
  "INFO: 4 uk postcodes scrubbed.\n",
746
746
  "INFO: Scrubbing titles using regex...\n",
747
747
  "INFO: 0 titles scrubbed.\n",
748
- "100%|██████████| 3/3 [00:08<00:00, 2.94s/it]\n"
748
+ "100%|██████████| 3/3 [00:07<00:00, 2.43s/it]\n"
749
749
  ]
750
750
  },
751
751
  {
@@ -851,7 +851,7 @@
851
851
  "4 They did not expected a reply from [EMAIL_ADDR... "
852
852
  ]
853
853
  },
854
- "execution_count": 21,
854
+ "execution_count": 10,
855
855
  "metadata": {},
856
856
  "output_type": "execute_result"
857
857
  }
@@ -866,7 +866,7 @@
866
866
  },
867
867
  {
868
868
  "cell_type": "code",
869
- "execution_count": 22,
869
+ "execution_count": 11,
870
870
  "metadata": {},
871
871
  "outputs": [
872
872
  {
@@ -1050,7 +1050,7 @@
1050
1050
  "8 [EH8 8DX] "
1051
1051
  ]
1052
1052
  },
1053
- "execution_count": 22,
1053
+ "execution_count": 11,
1054
1054
  "metadata": {},
1055
1055
  "output_type": "execute_result"
1056
1056
  }