rdt 1.5.1.dev1__tar.gz → 1.6.0__tar.gz

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.
Files changed (88) hide show
  1. {rdt-1.5.1.dev1 → rdt-1.6.0}/HISTORY.md +24 -0
  2. {rdt-1.5.1.dev1 → rdt-1.6.0}/PKG-INFO +25 -1
  3. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/__init__.py +1 -1
  4. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/pii/anonymizer.py +25 -1
  5. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/PKG-INFO +25 -1
  6. {rdt-1.5.1.dev1 → rdt-1.6.0}/setup.cfg +1 -1
  7. {rdt-1.5.1.dev1 → rdt-1.6.0}/setup.py +1 -1
  8. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/pii/test_anonymizer.py +21 -1
  9. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/pii/test_anonymizer.py +40 -2
  10. {rdt-1.5.1.dev1 → rdt-1.6.0}/AUTHORS.rst +0 -0
  11. {rdt-1.5.1.dev1 → rdt-1.6.0}/CONTRIBUTING.rst +0 -0
  12. {rdt-1.5.1.dev1 → rdt-1.6.0}/LICENSE +0 -0
  13. {rdt-1.5.1.dev1 → rdt-1.6.0}/MANIFEST.in +0 -0
  14. {rdt-1.5.1.dev1 → rdt-1.6.0}/README.md +0 -0
  15. {rdt-1.5.1.dev1 → rdt-1.6.0}/RELEASE.md +0 -0
  16. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/errors.py +0 -0
  17. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/hyper_transformer.py +0 -0
  18. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/__init__.py +0 -0
  19. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/__init__.py +0 -0
  20. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/base.py +0 -0
  21. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/boolean.py +0 -0
  22. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/categorical.py +0 -0
  23. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/datetime.py +0 -0
  24. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/numerical.py +0 -0
  25. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/pii.py +0 -0
  26. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/text.py +0 -0
  27. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/datasets/utils.py +0 -0
  28. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/performance.py +0 -0
  29. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/performance/profiling.py +0 -0
  30. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/__init__.py +0 -0
  31. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/addons/addons_setup.py +0 -0
  32. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/base.py +0 -0
  33. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/boolean.py +0 -0
  34. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/categorical.py +0 -0
  35. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/datetime.py +0 -0
  36. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/null.py +0 -0
  37. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/numerical.py +0 -0
  38. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/pii/__init__.py +0 -0
  39. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/pii/utils.py +0 -0
  40. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/text.py +0 -0
  41. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt/transformers/utils.py +0 -0
  42. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/SOURCES.txt +0 -0
  43. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/dependency_links.txt +0 -0
  44. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/not-zip-safe +0 -0
  45. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/requires.txt +0 -0
  46. {rdt-1.5.1.dev1 → rdt-1.6.0}/rdt.egg-info/top_level.txt +0 -0
  47. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/__init__.py +0 -0
  48. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/code_style.py +0 -0
  49. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/contributing.py +0 -0
  50. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/datasets/tests/test_boolean.py +0 -0
  51. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/datasets/tests/test_categorical.py +0 -0
  52. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/datasets/tests/test_datetime.py +0 -0
  53. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/datasets/tests/test_numerical.py +0 -0
  54. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/datasets/tests/test_utils.py +0 -0
  55. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/__init__.py +0 -0
  56. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/test_hyper_transformer.py +0 -0
  57. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/test_transformers.py +0 -0
  58. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/__init__.py +0 -0
  59. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/pii/__init__.py +0 -0
  60. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_base.py +0 -0
  61. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_boolean.py +0 -0
  62. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_categorical.py +0 -0
  63. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_datetime.py +0 -0
  64. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_numerical.py +0 -0
  65. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/integration/transformers/test_text.py +0 -0
  66. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/performance/README.md +0 -0
  67. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/performance/__init__.py +0 -0
  68. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/performance/test_performance.py +0 -0
  69. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/performance/tests/__init__.py +0 -0
  70. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/performance/tests/test_profiling.py +0 -0
  71. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/__init__.py +0 -0
  72. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/test___init__.py +0 -0
  73. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/test_hyper_transformer.py +0 -0
  74. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/__init__.py +0 -0
  75. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/addons/__init__.py +0 -0
  76. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/addons/identity/__init__.py +0 -0
  77. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/addons/identity/test_identity.py +0 -0
  78. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/pii/__init__.py +0 -0
  79. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/pii/test_utils.py +0 -0
  80. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test___init__.py +0 -0
  81. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_base.py +0 -0
  82. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_boolean.py +0 -0
  83. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_categorical.py +0 -0
  84. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_datetime.py +0 -0
  85. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_null.py +0 -0
  86. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_numerical.py +0 -0
  87. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_text.py +0 -0
  88. {rdt-1.5.1.dev1 → rdt-1.6.0}/tests/unit/transformers/test_utils.py +0 -0
@@ -1,5 +1,29 @@
1
1
  # History
2
2
 
3
+ ## 1.6.0 -2023-07-12
4
+
5
+ This release adds the ability to generate missing values to the `AnonymizedFaker`. Users can now provide the `missing_value_generation` parameter during initialization. They can set it to `None` to not generate any missing values, or `'random'` to generate random missing values in the same proportion as the fitted data.
6
+
7
+ Additionally, this release improves the `NullTransformer` by allowing nulls to be replaced on the forward transform even if `missing_value_generation` is set to None. It also fixes a bug that was causing the `UnixTimestampEncoder` to return a different dtype than the input on `reverse_transform`. This was particularly problematic when datetime columns are represented as ints.
8
+
9
+ ### New Features
10
+
11
+ * AnonymizedFaker should be able to model and generate missing values - Issue [#660](https://github.com/sdv-dev/RDT/issues/660) by @R-Palazzo
12
+
13
+ ### Bugs
14
+
15
+ * The datetime transformers don't give me back the same dtype sometimes - Issue [#657](https://github.com/sdv-dev/RDT/issues/657) by @frances-h
16
+ * RDT NullTransformer doesn't replace nulls if missing_value_generation is None - Issue [#658](https://github.com/sdv-dev/RDT/issues/658) by @amontanez24
17
+
18
+ ### Maintenance
19
+
20
+ * Remove python 3.7 builds - Issue [#663](https://github.com/sdv-dev/RDT/issues/663) by @amontanez24
21
+ * Drop support for Python 3.7 - Issue [#666](https://github.com/sdv-dev/RDT/issues/666) by @amontanez24
22
+
23
+ ### Internal
24
+
25
+ * Add add-on modules to sys.modules - Issue [#653](https://github.com/sdv-dev/RDT/issues/653) by @amontanez24
26
+
3
27
  ## 1.5.0 - 2023-06-01
4
28
 
5
29
  This release adds a new parameter called `missing_value_generation` to the initialization of certain transformers to specify how missing values should be created. The parameter can be used in the `FloatFormatter`, `BinaryEncoder`, `UnixTimestampEncoder`, `OptimizedTimestampEncoder`, `GaussianNormalizer` and `ClusterBasedNormalizer`. Additionally, it fixes a bug that was causing every column that had nulls to generate them in the same place.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rdt
3
- Version: 1.5.1.dev1
3
+ Version: 1.6.0
4
4
  Summary: Reversible Data Transforms
5
5
  Home-page: https://github.com/sdv-dev/RDT
6
6
  Author: DataCebo, Inc.
@@ -225,6 +225,30 @@ for specific needs.
225
225
 
226
226
  # History
227
227
 
228
+ ## 1.6.0 -2023-07-12
229
+
230
+ This release adds the ability to generate missing values to the `AnonymizedFaker`. Users can now provide the `missing_value_generation` parameter during initialization. They can set it to `None` to not generate any missing values, or `'random'` to generate random missing values in the same proportion as the fitted data.
231
+
232
+ Additionally, this release improves the `NullTransformer` by allowing nulls to be replaced on the forward transform even if `missing_value_generation` is set to None. It also fixes a bug that was causing the `UnixTimestampEncoder` to return a different dtype than the input on `reverse_transform`. This was particularly problematic when datetime columns are represented as ints.
233
+
234
+ ### New Features
235
+
236
+ * AnonymizedFaker should be able to model and generate missing values - Issue [#660](https://github.com/sdv-dev/RDT/issues/660) by @R-Palazzo
237
+
238
+ ### Bugs
239
+
240
+ * The datetime transformers don't give me back the same dtype sometimes - Issue [#657](https://github.com/sdv-dev/RDT/issues/657) by @frances-h
241
+ * RDT NullTransformer doesn't replace nulls if missing_value_generation is None - Issue [#658](https://github.com/sdv-dev/RDT/issues/658) by @amontanez24
242
+
243
+ ### Maintenance
244
+
245
+ * Remove python 3.7 builds - Issue [#663](https://github.com/sdv-dev/RDT/issues/663) by @amontanez24
246
+ * Drop support for Python 3.7 - Issue [#666](https://github.com/sdv-dev/RDT/issues/666) by @amontanez24
247
+
248
+ ### Internal
249
+
250
+ * Add add-on modules to sys.modules - Issue [#653](https://github.com/sdv-dev/RDT/issues/653) by @amontanez24
251
+
228
252
  ## 1.5.0 - 2023-06-01
229
253
 
230
254
  This release adds a new parameter called `missing_value_generation` to the initialization of certain transformers to specify how missing values should be created. The parameter can be used in the `FloatFormatter`, `BinaryEncoder`, `UnixTimestampEncoder`, `OptimizedTimestampEncoder`, `GaussianNormalizer` and `ClusterBasedNormalizer`. Additionally, it fixes a bug that was causing every column that had nulls to generate them in the same place.
@@ -5,7 +5,7 @@
5
5
 
6
6
  __author__ = 'DataCebo, Inc.'
7
7
  __email__ = 'info@sdv.dev'
8
- __version__ = '1.5.1.dev1'
8
+ __version__ = '1.6.0'
9
9
 
10
10
 
11
11
  import sys
@@ -36,6 +36,14 @@ class AnonymizedFaker(BaseTransformer):
36
36
  Whether or not to ensure that the new anonymized data is all unique. If it isn't
37
37
  possible to create the requested number of rows, then an error will be raised.
38
38
  Defaults to ``False``.
39
+ missing_value_generation (str or None):
40
+ The way missing values are being handled. There are two strategies:
41
+
42
+ * ``random``: Randomly generates missing values based on the percentage of
43
+ missing values.
44
+ * ``None``: Don't learn anything during fit. Then during reverse transform,
45
+ don't create any missing values.
46
+
39
47
  """
40
48
 
41
49
  IS_GENERATOR = True
@@ -85,7 +93,7 @@ class AnonymizedFaker(BaseTransformer):
85
93
  )
86
94
 
87
95
  def __init__(self, provider_name=None, function_name=None, function_kwargs=None,
88
- locales=None, enforce_uniqueness=False):
96
+ locales=None, enforce_uniqueness=False, missing_value_generation='random'):
89
97
  super().__init__()
90
98
  self.data_length = None
91
99
  self.enforce_uniqueness = enforce_uniqueness
@@ -107,6 +115,15 @@ class AnonymizedFaker(BaseTransformer):
107
115
  if self.locales:
108
116
  self._check_locales()
109
117
 
118
+ if missing_value_generation not in ['random', None]:
119
+ raise TransformerInputError(
120
+ f"Missing value generation '{missing_value_generation}' is not supported "
121
+ "for AnonymizedFaker. Please use either 'random' or None."
122
+ )
123
+
124
+ self.missing_value_generation = missing_value_generation
125
+ self._nan_frequency = 0.0
126
+
110
127
  def reset_randomization(self):
111
128
  """Create a new ``Faker`` instance."""
112
129
  super().reset_randomization()
@@ -138,6 +155,8 @@ class AnonymizedFaker(BaseTransformer):
138
155
  """
139
156
  self._set_faker_seed(data)
140
157
  self.data_length = len(data)
158
+ if self.missing_value_generation == 'random':
159
+ self._nan_frequency = data.isna().sum() / len(data)
141
160
 
142
161
  def _transform(self, _data):
143
162
  """Drop the input column by returning ``None``."""
@@ -170,6 +189,11 @@ class AnonymizedFaker(BaseTransformer):
170
189
  f"('{self.get_input_column()}')."
171
190
  ) from exception
172
191
 
192
+ if self.missing_value_generation == 'random':
193
+ num_nans = int(self._nan_frequency * sample_size)
194
+ nan_indices = np.random.choice(sample_size, num_nans, replace=False)
195
+ reverse_transformed[nan_indices] = np.nan
196
+
173
197
  return reverse_transformed
174
198
 
175
199
  def __repr__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rdt
3
- Version: 1.5.1.dev1
3
+ Version: 1.6.0
4
4
  Summary: Reversible Data Transforms
5
5
  Home-page: https://github.com/sdv-dev/RDT
6
6
  Author: DataCebo, Inc.
@@ -225,6 +225,30 @@ for specific needs.
225
225
 
226
226
  # History
227
227
 
228
+ ## 1.6.0 -2023-07-12
229
+
230
+ This release adds the ability to generate missing values to the `AnonymizedFaker`. Users can now provide the `missing_value_generation` parameter during initialization. They can set it to `None` to not generate any missing values, or `'random'` to generate random missing values in the same proportion as the fitted data.
231
+
232
+ Additionally, this release improves the `NullTransformer` by allowing nulls to be replaced on the forward transform even if `missing_value_generation` is set to None. It also fixes a bug that was causing the `UnixTimestampEncoder` to return a different dtype than the input on `reverse_transform`. This was particularly problematic when datetime columns are represented as ints.
233
+
234
+ ### New Features
235
+
236
+ * AnonymizedFaker should be able to model and generate missing values - Issue [#660](https://github.com/sdv-dev/RDT/issues/660) by @R-Palazzo
237
+
238
+ ### Bugs
239
+
240
+ * The datetime transformers don't give me back the same dtype sometimes - Issue [#657](https://github.com/sdv-dev/RDT/issues/657) by @frances-h
241
+ * RDT NullTransformer doesn't replace nulls if missing_value_generation is None - Issue [#658](https://github.com/sdv-dev/RDT/issues/658) by @amontanez24
242
+
243
+ ### Maintenance
244
+
245
+ * Remove python 3.7 builds - Issue [#663](https://github.com/sdv-dev/RDT/issues/663) by @amontanez24
246
+ * Drop support for Python 3.7 - Issue [#666](https://github.com/sdv-dev/RDT/issues/666) by @amontanez24
247
+
248
+ ### Internal
249
+
250
+ * Add add-on modules to sys.modules - Issue [#653](https://github.com/sdv-dev/RDT/issues/653) by @amontanez24
251
+
228
252
  ## 1.5.0 - 2023-06-01
229
253
 
230
254
  This release adds a new parameter called `missing_value_generation` to the initialization of certain transformers to specify how missing values should be created. The parameter can be used in the `FloatFormatter`, `BinaryEncoder`, `UnixTimestampEncoder`, `OptimizedTimestampEncoder`, `GaussianNormalizer` and `ClusterBasedNormalizer`. Additionally, it fixes a bug that was causing every column that had nulls to generate them in the same place.
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 1.5.1.dev1
2
+ current_version = 1.6.0
3
3
  commit = True
4
4
  tag = True
5
5
  parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?
@@ -139,6 +139,6 @@ setup(
139
139
  test_suite='tests',
140
140
  tests_require=tests_require,
141
141
  url='https://github.com/sdv-dev/RDT',
142
- version='1.5.1.dev1',
142
+ version='1.6.0',
143
143
  zip_safe=False,
144
144
  )
@@ -69,6 +69,26 @@ def test_anonymizedfaker_with_nans():
69
69
  'id': [1, 2, 3, 4, 5],
70
70
  })
71
71
 
72
+ pd.testing.assert_frame_equal(transformed, expected_transformed)
73
+ assert len(reverse_transform['username']) == 5
74
+ assert reverse_transform['username'].isna().sum() == 1
75
+
76
+
77
+ def test_anonymizedfaker_with_nans_missing_value_generation_none():
78
+ """End to end test settings missing_value_generation=None."""
79
+ data = pd.DataFrame({
80
+ 'id': [1, 2, 3, 4, 5],
81
+ 'username': ['a', np.nan, 'c', 'd', 'e']
82
+ })
83
+
84
+ instance = AnonymizedFaker(missing_value_generation=None)
85
+ transformed = instance.fit_transform(data, 'username')
86
+ reverse_transform = instance.reverse_transform(transformed)
87
+
88
+ expected_transformed = pd.DataFrame({
89
+ 'id': [1, 2, 3, 4, 5],
90
+ })
91
+
72
92
  pd.testing.assert_frame_equal(transformed, expected_transformed)
73
93
  assert len(reverse_transform['username']) == 5
74
94
  assert reverse_transform['username'].isna().sum() == 0
@@ -102,7 +122,7 @@ def test_anonymizedfaker_custom_provider_with_nans():
102
122
 
103
123
  pd.testing.assert_frame_equal(transformed, expected_transformed)
104
124
  assert len(reverse_transform['cc']) == 5
105
- assert reverse_transform['cc'].isna().sum() == 0
125
+ assert reverse_transform['cc'].isna().sum() == 1
106
126
 
107
127
 
108
128
  def test_anonymizedfaker_enforce_uniqueness():
@@ -220,6 +220,23 @@ class TestAnonymizedFaker:
220
220
  assert instance.locales is None
221
221
  assert mock_faker.Faker.called_once_with(None)
222
222
  assert instance.enforce_uniqueness is False
223
+ assert instance.missing_value_generation == 'random'
224
+
225
+ def test___init__error_missing_value_generation(self):
226
+ """Test that the ``__init__`` raises an error if the missing value generation is invalid.
227
+
228
+ Test that the ``__init__`` raises an error if the missing value generation is invalid.
229
+
230
+ Side effects:
231
+ - ``ValueError`` is raised.
232
+ """
233
+ expected_message = (
234
+ "Missing value generation 'invalid' is not supported "
235
+ "for AnonymizedFaker. Please use either 'random' or None."
236
+ )
237
+ # Run and Assert
238
+ with pytest.raises(TransformerInputError, match=expected_message):
239
+ AnonymizedFaker(missing_value_generation='invalid')
223
240
 
224
241
  @patch('rdt.transformers.pii.anonymizer.faker')
225
242
  @patch('rdt.transformers.pii.anonymizer.AnonymizedFaker.check_provider_function')
@@ -312,15 +329,16 @@ class TestAnonymizedFaker:
312
329
  """
313
330
  # Setup
314
331
  transformer = AnonymizedFaker()
315
- columns_data = pd.Series(['1', '2', '3'])
332
+ columns_data = pd.Series(['1', '2', '3', None, np.nan])
316
333
  transformer.columns = ['col']
317
334
 
318
335
  # Run
319
336
  transformer._fit(columns_data)
320
337
 
321
338
  # Assert
322
- assert transformer.data_length == 3
339
+ assert transformer.data_length == 5
323
340
  assert transformer.output_properties == {None: {'next_transformer': None}}
341
+ assert transformer._nan_frequency == 0.4
324
342
 
325
343
  def test__transform(self):
326
344
  """Test the ``_transform`` method.
@@ -377,6 +395,26 @@ class TestAnonymizedFaker:
377
395
  assert function.call_args_list == [call(), call(), call()]
378
396
  np.testing.assert_array_equal(result, np.array(['a', 'b', 'c']))
379
397
 
398
+ def test__reverse_transform_with_nans(self):
399
+ """Test that ``_reverse_transform`` generates NaNs."""
400
+ # Setup
401
+ instance = AnonymizedFaker()
402
+ instance.data_length = 4
403
+ instance._nan_frequency = 0.25
404
+ function = Mock()
405
+ function.side_effect = ['a', 'b', 'c', 'd']
406
+
407
+ instance._function = function
408
+
409
+ # Run
410
+ result = instance._reverse_transform(None)
411
+ result = pd.Series(result)
412
+
413
+ # Assert
414
+ assert function.call_args_list == [call(), call(), call(), call()]
415
+ assert instance.missing_value_generation == 'random'
416
+ assert result.isna().sum() == 1
417
+
380
418
  def test__reverse_transform_not_enough_unique_values(self):
381
419
  """Test the ``_reverse_transform`` method.
382
420
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes