sdv 1.38.5.dev1__tar.gz → 2.0.0.dev0__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.
- {sdv-1.38.5.dev1/sdv.egg-info → sdv-2.0.0.dev0}/PKG-INFO +4 -5
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/README.md +2 -2
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/pyproject.toml +2 -3
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/__init__.py +1 -5
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/_utils.py +165 -29
- sdv-1.38.5.dev1/sdv/constraints/utils.py → sdv-2.0.0.dev0/sdv/cag/_utils.py +280 -69
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/base.py +13 -8
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/fixed_combinations.py +5 -4
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/inequality.py +5 -8
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/one_hot_encoding.py +11 -12
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/range.py +8 -11
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/data_processor.py +45 -101
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/numerical_formatter.py +8 -21
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/datasets/demo.py +33 -42
- sdv-2.0.0.dev0/sdv/evaluation/__init__.py +20 -0
- sdv-2.0.0.dev0/sdv/evaluation/_visualization.py +266 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/logging/sdv_logger_config.yml +14 -14
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metadata/__init__.py +0 -4
- sdv-1.38.5.dev1/sdv/metadata/single_table.py → sdv-2.0.0.dev0/sdv/metadata/_single_table.py +386 -105
- sdv-1.38.5.dev1/sdv/metadata/multi_table.py → sdv-2.0.0.dev0/sdv/metadata/metadata.py +445 -114
- sdv-2.0.0.dev0/sdv/metadata/metadata_upgrader.py +63 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metadata/utils.py +6 -12
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metadata/visualization.py +1 -1
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/multi_table/base.py +138 -137
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/multi_table/hma.py +5 -8
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/multi_table/utils.py +13 -13
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sampling/hierarchical_sampler.py +90 -14
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sampling/independent_sampler.py +35 -8
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sequential/par.py +128 -82
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/base.py +153 -215
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/copulagan.py +2 -9
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/copulas.py +1 -2
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/ctgan.py +8 -21
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/dayz.py +2 -2
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/utils.py +40 -1
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/utils/__init__.py +5 -1
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/utils/utils.py +132 -4
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0/sdv.egg-info}/PKG-INFO +4 -5
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv.egg-info/SOURCES.txt +3 -14
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv.egg-info/requires.txt +1 -2
- sdv-1.38.5.dev1/sdv/cag/_utils.py +0 -299
- sdv-1.38.5.dev1/sdv/constraints/__init__.py +0 -31
- sdv-1.38.5.dev1/sdv/constraints/base.py +0 -524
- sdv-1.38.5.dev1/sdv/constraints/errors.py +0 -38
- sdv-1.38.5.dev1/sdv/constraints/tabular.py +0 -1502
- sdv-1.38.5.dev1/sdv/evaluation/__init__.py +0 -12
- sdv-1.38.5.dev1/sdv/evaluation/_utils.py +0 -35
- sdv-1.38.5.dev1/sdv/evaluation/multi_table.py +0 -212
- sdv-1.38.5.dev1/sdv/evaluation/single_table.py +0 -206
- sdv-1.38.5.dev1/sdv/lite/__init__.py +0 -5
- sdv-1.38.5.dev1/sdv/lite/single_table.py +0 -223
- sdv-1.38.5.dev1/sdv/metadata/metadata.py +0 -549
- sdv-1.38.5.dev1/sdv/metadata/metadata_upgrader.py +0 -312
- sdv-1.38.5.dev1/sdv/utils/poc.py +0 -141
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/LICENSE +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/_errors.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/fixed_increments.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/cag/programmable_constraint.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/datetime_formatter.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/errors.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/data_processing/utils.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/datasets/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/datasets/_utils.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/datasets/local.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/errors.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/evaluation/evaluation.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/evaluation/utils.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/io/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/io/local/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/io/local/local.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/logging/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/logging/logger.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/logging/utils.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metadata/errors.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metrics/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metrics/demos.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metrics/relational.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metrics/tabular.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/metrics/timeseries.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/multi_table/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/multi_table/dayz.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sampling/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sampling/tabular.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/sequential/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/single_table/__init__.py +0 -0
- {sdv-1.38.5.dev1/sdv/utils → sdv-2.0.0.dev0/sdv/single_table}/mixins.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv/version/__init__.py +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv.egg-info/dependency_links.txt +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv.egg-info/entry_points.txt +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/sdv.egg-info/top_level.txt +0 -0
- {sdv-1.38.5.dev1 → sdv-2.0.0.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdv
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0.dev0
|
|
4
4
|
Summary: Generate synthetic data for single table, multi table and sequential data
|
|
5
5
|
Author-email: "DataCebo, Inc." <info@sdv.dev>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -46,8 +46,7 @@ Requires-Dist: ctgan>=0.11.1; python_version < "3.14"
|
|
|
46
46
|
Requires-Dist: ctgan>=0.12.0; python_version >= "3.14"
|
|
47
47
|
Requires-Dist: deepecho>=0.7.0; python_version < "3.14"
|
|
48
48
|
Requires-Dist: deepecho>=0.8.0; python_version >= "3.14"
|
|
49
|
-
Requires-Dist: rdt
|
|
50
|
-
Requires-Dist: rdt<2,>=1.20.0; python_version >= "3.14"
|
|
49
|
+
Requires-Dist: rdt>=2.0.0.dev0
|
|
51
50
|
Requires-Dist: sdmetrics>=0.32.0
|
|
52
51
|
Requires-Dist: platformdirs>=4.0
|
|
53
52
|
Requires-Dist: pyyaml>=6.0.1
|
|
@@ -215,7 +214,7 @@ The SDV library allows you to evaluate the synthetic data by comparing it to the
|
|
|
215
214
|
started by generating a quality report.
|
|
216
215
|
|
|
217
216
|
```python
|
|
218
|
-
from sdv.evaluation
|
|
217
|
+
from sdv.evaluation import evaluate_quality
|
|
219
218
|
|
|
220
219
|
quality_report = evaluate_quality(real_data, synthetic_data, metadata)
|
|
221
220
|
```
|
|
@@ -236,7 +235,7 @@ This object computes an overall quality score on a scale of 0 to 100% (100 being
|
|
|
236
235
|
as detailed breakdowns. For more insights, you can also visualize the synthetic vs. real data.
|
|
237
236
|
|
|
238
237
|
```python
|
|
239
|
-
from sdv.evaluation
|
|
238
|
+
from sdv.evaluation import get_column_plot
|
|
240
239
|
|
|
241
240
|
fig = get_column_plot(
|
|
242
241
|
real_data=real_data,
|
|
@@ -119,7 +119,7 @@ The SDV library allows you to evaluate the synthetic data by comparing it to the
|
|
|
119
119
|
started by generating a quality report.
|
|
120
120
|
|
|
121
121
|
```python
|
|
122
|
-
from sdv.evaluation
|
|
122
|
+
from sdv.evaluation import evaluate_quality
|
|
123
123
|
|
|
124
124
|
quality_report = evaluate_quality(real_data, synthetic_data, metadata)
|
|
125
125
|
```
|
|
@@ -140,7 +140,7 @@ This object computes an overall quality score on a scale of 0 to 100% (100 being
|
|
|
140
140
|
as detailed breakdowns. For more insights, you can also visualize the synthetic vs. real data.
|
|
141
141
|
|
|
142
142
|
```python
|
|
143
|
-
from sdv.evaluation
|
|
143
|
+
from sdv.evaluation import get_column_plot
|
|
144
144
|
|
|
145
145
|
fig = get_column_plot(
|
|
146
146
|
real_data=real_data,
|
|
@@ -44,8 +44,7 @@ dependencies = [
|
|
|
44
44
|
"ctgan>=0.12.0;python_version>='3.14'",
|
|
45
45
|
"deepecho>=0.7.0;python_version<'3.14'",
|
|
46
46
|
"deepecho>=0.8.0;python_version>='3.14'",
|
|
47
|
-
"rdt>=
|
|
48
|
-
"rdt>=1.20.0,<2;python_version>='3.14'",
|
|
47
|
+
"rdt>=2.0.0.dev0",
|
|
49
48
|
"sdmetrics>=0.32.0",
|
|
50
49
|
'platformdirs>=4.0',
|
|
51
50
|
'pyyaml>=6.0.1',
|
|
@@ -149,7 +148,7 @@ namespaces = false
|
|
|
149
148
|
version = {attr = 'sdv.__version__'}
|
|
150
149
|
|
|
151
150
|
[tool.bumpversion]
|
|
152
|
-
current_version = "
|
|
151
|
+
current_version = "2.0.0.dev0"
|
|
153
152
|
parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?'
|
|
154
153
|
serialize = [
|
|
155
154
|
'{major}.{minor}.{patch}.{release}{candidate}',
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
__author__ = 'DataCebo, Inc.'
|
|
8
8
|
__email__ = 'info@sdv.dev'
|
|
9
|
-
__version__ = '
|
|
9
|
+
__version__ = '2.0.0.dev0'
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
import sys
|
|
@@ -16,12 +16,10 @@ from operator import attrgetter
|
|
|
16
16
|
from types import ModuleType
|
|
17
17
|
|
|
18
18
|
from sdv import (
|
|
19
|
-
constraints,
|
|
20
19
|
data_processing,
|
|
21
20
|
datasets,
|
|
22
21
|
evaluation,
|
|
23
22
|
io,
|
|
24
|
-
lite,
|
|
25
23
|
logging,
|
|
26
24
|
metadata,
|
|
27
25
|
metrics,
|
|
@@ -34,12 +32,10 @@ from sdv import (
|
|
|
34
32
|
)
|
|
35
33
|
|
|
36
34
|
__all__ = [
|
|
37
|
-
'constraints',
|
|
38
35
|
'data_processing',
|
|
39
36
|
'datasets',
|
|
40
37
|
'evaluation',
|
|
41
38
|
'io',
|
|
42
|
-
'lite',
|
|
43
39
|
'logging',
|
|
44
40
|
'metadata',
|
|
45
41
|
'metrics',
|
|
@@ -9,13 +9,14 @@ from collections.abc import Iterable
|
|
|
9
9
|
from datetime import datetime
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
+
import numpy as np
|
|
12
13
|
import pandas as pd
|
|
13
14
|
from pandas.api.types import is_float, is_integer
|
|
14
15
|
from pandas.core.tools.datetimes import _guess_datetime_format_for_array
|
|
15
16
|
from rdt.transformers.utils import _GENERATORS, strings_from_regex
|
|
16
17
|
|
|
17
18
|
from sdv import version
|
|
18
|
-
from sdv.errors import SDVVersionWarning, SynthesizerInputError, VersionError
|
|
19
|
+
from sdv.errors import InvalidDataTypeError, SDVVersionWarning, SynthesizerInputError, VersionError
|
|
19
20
|
|
|
20
21
|
try:
|
|
21
22
|
from re import _parser as sre_parse
|
|
@@ -23,7 +24,7 @@ except ImportError:
|
|
|
23
24
|
import sre_parse
|
|
24
25
|
|
|
25
26
|
|
|
26
|
-
MODELABLE_SDTYPES = ['categorical', 'numerical', 'datetime', 'boolean']
|
|
27
|
+
MODELABLE_SDTYPES = ['categorical', 'ordinal', 'numerical', 'datetime', 'boolean']
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def _cast_to_iterable(value, iterable_type=None):
|
|
@@ -161,6 +162,82 @@ def _datetime_string_matches_format(value, datetime_format):
|
|
|
161
162
|
return False
|
|
162
163
|
|
|
163
164
|
|
|
165
|
+
def _parse_datetime(value, datetime_format, ignore_timezone):
|
|
166
|
+
is_series = isinstance(value, pd.Series)
|
|
167
|
+
parsed_value = pd.to_datetime(value, format=datetime_format, errors='coerce')
|
|
168
|
+
|
|
169
|
+
if is_series and ignore_timezone and hasattr(parsed_value, 'dt'):
|
|
170
|
+
if hasattr(parsed_value.dt, 'tz_localize'):
|
|
171
|
+
parsed_value = parsed_value.dt.tz_localize(None)
|
|
172
|
+
|
|
173
|
+
elif ignore_timezone and hasattr(parsed_value, 'tz_localize'):
|
|
174
|
+
if isinstance(parsed_value, (list, tuple, pd.Series, np.ndarray)):
|
|
175
|
+
parsed_value = [
|
|
176
|
+
new_value.replace(tzinfo=None)
|
|
177
|
+
if isinstance(new_value, datetime)
|
|
178
|
+
else new_value.tz_localize(None)
|
|
179
|
+
for new_value in parsed_value
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
else:
|
|
183
|
+
parsed_value = parsed_value.tz_localize(None)
|
|
184
|
+
|
|
185
|
+
if is_series and not isinstance(parsed_value, pd.Series):
|
|
186
|
+
return pd.Series(parsed_value)
|
|
187
|
+
|
|
188
|
+
return parsed_value
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _parse_datetime64_value(value, datetime_format=None, ignore_timezone=True):
|
|
192
|
+
"""Parse a single value into `datetime64`, optionally ignoring timezone."""
|
|
193
|
+
if pd.isna(value):
|
|
194
|
+
return pd.NaT.to_datetime64()
|
|
195
|
+
|
|
196
|
+
return _parse_datetime(value, datetime_format, ignore_timezone).to_datetime64()
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _cast_to_datetime64(value, datetime_format=None, ignore_timezone=True):
|
|
200
|
+
"""Cast a given value to a ``numpy.datetime64`` format.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
value (pandas.Series, np.ndarray, list, or str):
|
|
204
|
+
Input data to convert.
|
|
205
|
+
datetime_format (str, optional):
|
|
206
|
+
Datetime format of the `value`.
|
|
207
|
+
ignore_timezone (bool):
|
|
208
|
+
If True, strips `%z` or `%Z` from the format and removes tzinfo.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
numpy.datetime64, pandas.Series, or numpy.ndarray of datetime64
|
|
212
|
+
"""
|
|
213
|
+
if datetime_format:
|
|
214
|
+
datetime_format = datetime_format.replace('%#', '%').replace('%-', '%')
|
|
215
|
+
|
|
216
|
+
if isinstance(value, str):
|
|
217
|
+
return _parse_datetime64_value(value, datetime_format, ignore_timezone)
|
|
218
|
+
|
|
219
|
+
elif isinstance(value, pd.Series):
|
|
220
|
+
return pd.Series(
|
|
221
|
+
[
|
|
222
|
+
_parse_datetime64_value(
|
|
223
|
+
val,
|
|
224
|
+
datetime_format,
|
|
225
|
+
ignore_timezone,
|
|
226
|
+
)
|
|
227
|
+
for val in value
|
|
228
|
+
],
|
|
229
|
+
index=value.index,
|
|
230
|
+
dtype='datetime64[ns]',
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
elif isinstance(value, (np.ndarray, list)):
|
|
234
|
+
return np.array([
|
|
235
|
+
_parse_datetime64_value(val, datetime_format, ignore_timezone) for val in value
|
|
236
|
+
])
|
|
237
|
+
|
|
238
|
+
return _parse_datetime64_value(value, datetime_format, ignore_timezone)
|
|
239
|
+
|
|
240
|
+
|
|
164
241
|
def _convert_to_timedelta(column):
|
|
165
242
|
"""Convert a ``pandas.Series`` to one with dtype ``timedelta``.
|
|
166
243
|
|
|
@@ -266,7 +343,7 @@ def check_sdv_versions_and_warn(synthesizer):
|
|
|
266
343
|
"""Check if the current SDV and SDV Enterprise versions mismatch.
|
|
267
344
|
|
|
268
345
|
Args:
|
|
269
|
-
synthesizer (BaseSynthesizer
|
|
346
|
+
synthesizer (BaseSynthesizer):
|
|
270
347
|
An SDV model instance to check versions against.
|
|
271
348
|
|
|
272
349
|
Raises:
|
|
@@ -359,7 +436,7 @@ def check_synthesizer_version(synthesizer, is_fit_method=False, compare_operator
|
|
|
359
436
|
"""Check if the current synthesizer version is greater than the package version.
|
|
360
437
|
|
|
361
438
|
Args:
|
|
362
|
-
synthesizer (BaseSynthesizer
|
|
439
|
+
synthesizer (BaseSynthesizer):
|
|
363
440
|
An SDV model instance to check versions against.
|
|
364
441
|
is_fit_method (bool):
|
|
365
442
|
Whether or not this function is being called by a ``fit`` function.
|
|
@@ -435,7 +512,7 @@ def generate_synthesizer_id(synthesizer):
|
|
|
435
512
|
and the last part of a UUID4 composed by 36 random characters.
|
|
436
513
|
|
|
437
514
|
Args:
|
|
438
|
-
synthesizer (BaseSynthesizer
|
|
515
|
+
synthesizer (BaseSynthesizer):
|
|
439
516
|
An SDV model instance to check versions against.
|
|
440
517
|
|
|
441
518
|
Returns:
|
|
@@ -489,11 +566,7 @@ def _is_numerical(value):
|
|
|
489
566
|
def _get_transformer_init_kwargs(transformer):
|
|
490
567
|
"""Get the dict of arguments used to instantiate the given transformer."""
|
|
491
568
|
args = inspect.getfullargspec(transformer.__init__).args[1:]
|
|
492
|
-
return {
|
|
493
|
-
key: getattr(transformer, key)
|
|
494
|
-
for key in args
|
|
495
|
-
if key != 'model_missing_values' and hasattr(transformer, key)
|
|
496
|
-
}
|
|
569
|
+
return {key: getattr(transformer, key) for key in args if hasattr(transformer, key)}
|
|
497
570
|
|
|
498
571
|
|
|
499
572
|
def _check_regex_format(table_name, column_name, regex):
|
|
@@ -509,25 +582,6 @@ def _check_regex_format(table_name, column_name, regex):
|
|
|
509
582
|
) from e
|
|
510
583
|
|
|
511
584
|
|
|
512
|
-
def warn_load_deprecated():
|
|
513
|
-
"""Warn that the `load` function is deprecated."""
|
|
514
|
-
warnings.warn(
|
|
515
|
-
"The 'load' function will be deprecated in future versions of SDV. Please use"
|
|
516
|
-
" 'utils.load_synthesizer' instead.",
|
|
517
|
-
FutureWarning,
|
|
518
|
-
)
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
def warn_set_constraints_deprecated():
|
|
522
|
-
"""Warn that the `set_constraints` method on synthesizer is deprecated."""
|
|
523
|
-
deprecation_msg = (
|
|
524
|
-
'Warning: The `set_constraints` method is deprecated. '
|
|
525
|
-
'Please use the `load_constraints` utility function to load constraints from a file '
|
|
526
|
-
'and add them to the synthesizer with the `add_constraints` method.'
|
|
527
|
-
)
|
|
528
|
-
warnings.warn(deprecation_msg, FutureWarning)
|
|
529
|
-
|
|
530
|
-
|
|
531
585
|
def _validate_correct_synthesizer_loading(synthesizer, cls):
|
|
532
586
|
"""Validate that the loaded synthesizer is of the correct type."""
|
|
533
587
|
synthesizer_name = synthesizer.__class__.__name__
|
|
@@ -574,3 +628,85 @@ def _check_is_dict_of_dataframes(data, arg_name='data'):
|
|
|
574
628
|
for table_name, table in data.items():
|
|
575
629
|
if not isinstance(table, pd.DataFrame):
|
|
576
630
|
raise ValueError(error_message_data)
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
def _column_range_exceeds_real(column, col_meta):
|
|
634
|
+
range_is_nullable = col_meta.get('range_is_nullable', False)
|
|
635
|
+
if not any(pd.isna(column)) and range_is_nullable:
|
|
636
|
+
return True
|
|
637
|
+
|
|
638
|
+
column = column.dropna()
|
|
639
|
+
if col_meta['sdtype'] in ['datetime', 'numerical']:
|
|
640
|
+
range_min = col_meta.get('range_min')
|
|
641
|
+
range_max = col_meta.get('range_max')
|
|
642
|
+
if range_min is None and range_max is None:
|
|
643
|
+
return False
|
|
644
|
+
elif column.empty:
|
|
645
|
+
return True
|
|
646
|
+
|
|
647
|
+
if col_meta['sdtype'] == 'datetime':
|
|
648
|
+
datetime_format = col_meta.get('datetime_format')
|
|
649
|
+
column = _cast_to_datetime64(column, datetime_format)
|
|
650
|
+
if range_min is not None:
|
|
651
|
+
range_min = _cast_to_datetime64(range_min, datetime_format)
|
|
652
|
+
|
|
653
|
+
if range_max is not None:
|
|
654
|
+
range_max = _cast_to_datetime64(range_max, datetime_format)
|
|
655
|
+
|
|
656
|
+
min_bound_met = any(column.dropna() <= range_min) if range_min is not None else True
|
|
657
|
+
max_bound_met = any(column.dropna() >= range_max) if range_max is not None else True
|
|
658
|
+
return not (min_bound_met and max_bound_met)
|
|
659
|
+
|
|
660
|
+
elif col_meta['sdtype'] in ['categorical', 'ordinal']:
|
|
661
|
+
if 'range_values' not in col_meta:
|
|
662
|
+
return False
|
|
663
|
+
|
|
664
|
+
if not set(col_meta['range_values']).issubset(set(column.unique())):
|
|
665
|
+
return True
|
|
666
|
+
|
|
667
|
+
return False
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
def _metadata_range_exceeds_real(data, metadata):
|
|
671
|
+
"""Returns whether the metadata range information exceeds the real data range."""
|
|
672
|
+
for table_name, table_data in data.items():
|
|
673
|
+
for column in table_data.columns:
|
|
674
|
+
col_meta = metadata.tables[table_name].columns[column]
|
|
675
|
+
if _column_range_exceeds_real(table_data[column], col_meta):
|
|
676
|
+
return True
|
|
677
|
+
|
|
678
|
+
return False
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def _validate_data_single_table(data, table_name=None):
|
|
682
|
+
"""Validate that the data is a dictionary with a single table."""
|
|
683
|
+
if len(data) != 1:
|
|
684
|
+
raise InvalidDataTypeError(
|
|
685
|
+
'The `data` parameter must be a dictionary containing exactly one table name '
|
|
686
|
+
'mapped to a pandas DataFrame.'
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
if table_name is not None and table_name not in data:
|
|
690
|
+
raise InvalidDataTypeError(
|
|
691
|
+
f"The specified table name '{table_name}' is not present in the data."
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
def _get_single_table_data(data):
|
|
696
|
+
"""Return the single table DataFrame from the data dictionary."""
|
|
697
|
+
_validate_data_single_table(data)
|
|
698
|
+
return next(iter(data.values()))
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def _validate_positive_integer(parameter_name, value):
|
|
702
|
+
"""Validate that a parameter is a positive integer."""
|
|
703
|
+
if (
|
|
704
|
+
not isinstance(value, (int, float))
|
|
705
|
+
or value <= 0
|
|
706
|
+
or not float(value).is_integer()
|
|
707
|
+
or isinstance(value, bool)
|
|
708
|
+
):
|
|
709
|
+
raise SynthesizerInputError(
|
|
710
|
+
f"Invalid parameter for '{parameter_name}' ({value}). "
|
|
711
|
+
'Please provide an integer that is greater than 0.'
|
|
712
|
+
)
|