upgini 1.2.113a3__tar.gz → 1.2.113a4__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 (80) hide show
  1. {upgini-1.2.113a3 → upgini-1.2.113a4}/PKG-INFO +1 -1
  2. upgini-1.2.113a4/src/upgini/__about__.py +1 -0
  3. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/features_enricher.py +50 -82
  4. upgini-1.2.113a3/src/upgini/__about__.py +0 -1
  5. {upgini-1.2.113a3 → upgini-1.2.113a4}/.gitignore +0 -0
  6. {upgini-1.2.113a3 → upgini-1.2.113a4}/LICENSE +0 -0
  7. {upgini-1.2.113a3 → upgini-1.2.113a4}/README.md +0 -0
  8. {upgini-1.2.113a3 → upgini-1.2.113a4}/pyproject.toml +0 -0
  9. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/__init__.py +0 -0
  10. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/ads.py +0 -0
  11. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/ads_management/__init__.py +0 -0
  12. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/ads_management/ads_manager.py +0 -0
  13. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/__init__.py +0 -0
  14. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/all_operators.py +0 -0
  15. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/binary.py +0 -0
  16. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/date.py +0 -0
  17. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/feature.py +0 -0
  18. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/groupby.py +0 -0
  19. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/operator.py +0 -0
  20. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/__init__.py +0 -0
  21. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/base.py +0 -0
  22. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/cross.py +0 -0
  23. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/delta.py +0 -0
  24. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/lag.py +0 -0
  25. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/roll.py +0 -0
  26. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/trend.py +0 -0
  27. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/timeseries/volatility.py +0 -0
  28. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/unary.py +0 -0
  29. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/utils.py +0 -0
  30. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/autofe/vector.py +0 -0
  31. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/data_source/__init__.py +0 -0
  32. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/data_source/data_source_publisher.py +0 -0
  33. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/dataset.py +0 -0
  34. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/errors.py +0 -0
  35. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/http.py +0 -0
  36. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/mdc/__init__.py +0 -0
  37. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/mdc/context.py +0 -0
  38. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/metadata.py +0 -0
  39. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/metrics.py +0 -0
  40. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/normalizer/__init__.py +0 -0
  41. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/normalizer/normalize_utils.py +0 -0
  42. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/resource_bundle/__init__.py +0 -0
  43. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/resource_bundle/exceptions.py +0 -0
  44. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/resource_bundle/strings.properties +0 -0
  45. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/resource_bundle/strings_widget.properties +0 -0
  46. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/sampler/__init__.py +0 -0
  47. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/sampler/base.py +0 -0
  48. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/sampler/random_under_sampler.py +0 -0
  49. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/sampler/utils.py +0 -0
  50. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/search_task.py +0 -0
  51. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/spinner.py +0 -0
  52. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/Roboto-Regular.ttf +0 -0
  53. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/__init__.py +0 -0
  54. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/base_search_key_detector.py +0 -0
  55. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/blocked_time_series.py +0 -0
  56. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/country_utils.py +0 -0
  57. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/custom_loss_utils.py +0 -0
  58. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/cv_utils.py +0 -0
  59. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/datetime_utils.py +0 -0
  60. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/deduplicate_utils.py +0 -0
  61. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/display_utils.py +0 -0
  62. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/email_utils.py +0 -0
  63. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/fallback_progress_bar.py +0 -0
  64. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/feature_info.py +0 -0
  65. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/features_validator.py +0 -0
  66. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/format.py +0 -0
  67. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/ip_utils.py +0 -0
  68. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/mstats.py +0 -0
  69. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/phone_utils.py +0 -0
  70. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/postal_code_utils.py +0 -0
  71. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/progress_bar.py +0 -0
  72. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/psi.py +0 -0
  73. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/sample_utils.py +0 -0
  74. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/sklearn_ext.py +0 -0
  75. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/sort.py +0 -0
  76. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/target_utils.py +0 -0
  77. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/track_info.py +0 -0
  78. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/ts_utils.py +0 -0
  79. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/utils/warning_counter.py +0 -0
  80. {upgini-1.2.113a3 → upgini-1.2.113a4}/src/upgini/version_validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: upgini
3
- Version: 1.2.113a3
3
+ Version: 1.2.113a4
4
4
  Summary: Intelligent data search & enrichment for Machine Learning
5
5
  Project-URL: Bug Reports, https://github.com/upgini/upgini/issues
6
6
  Project-URL: Homepage, https://upgini.com/
@@ -0,0 +1 @@
1
+ __version__ = "1.2.113a4"
@@ -1059,24 +1059,9 @@ class FeaturesEnricher(TransformerMixin):
1059
1059
  groups,
1060
1060
  _cv,
1061
1061
  columns_renaming,
1062
- eval_set_dates,
1062
+ _,
1063
1063
  ) = prepared_data
1064
1064
 
1065
- # rename cat_features
1066
- if client_cat_features:
1067
- for new_c, old_c in columns_renaming.items():
1068
- if old_c in client_cat_features:
1069
- client_cat_features.remove(old_c)
1070
- client_cat_features.append(new_c)
1071
- for cat_feature in client_cat_features:
1072
- if cat_feature not in fitting_X.columns:
1073
- self.logger.error(
1074
- f"Client cat_feature `{cat_feature}` not found in"
1075
- f" x columns: {fitting_X.columns.to_list()}"
1076
- )
1077
- else:
1078
- client_cat_features = []
1079
-
1080
1065
  # rename baseline_score_column
1081
1066
  reversed_renaming = {v: k for k, v in columns_renaming.items()}
1082
1067
  baseline_score_column = self.baseline_score_column
@@ -1305,7 +1290,7 @@ class FeaturesEnricher(TransformerMixin):
1305
1290
  metrics.append(eval_metrics)
1306
1291
 
1307
1292
  if updating_shaps is not None:
1308
- decoded_X = self._decode_id_columns(fitting_X, columns_renaming)
1293
+ decoded_X = self._decode_id_columns(fitting_X)
1309
1294
  self._update_shap_values(trace_id, decoded_X, updating_shaps, silent=not internal_call)
1310
1295
 
1311
1296
  metrics_df = pd.DataFrame(metrics)
@@ -1376,12 +1361,23 @@ class FeaturesEnricher(TransformerMixin):
1376
1361
  if isinstance(X, np.ndarray):
1377
1362
  search_keys = {str(k): v for k, v in search_keys.items()}
1378
1363
 
1379
- has_date = self._get_date_column(search_keys) is not None
1380
- if not has_date or not validated_eval_set:
1381
- self.logger.info("No date column or eval set for OOT psi calculation")
1364
+ date_column = self._get_date_column(search_keys)
1365
+ has_date = date_column is not None
1366
+ if not has_date:
1367
+ self.logger.info("No date column for OOT PSI calculation")
1368
+ return
1369
+ if not validated_eval_set:
1370
+ self.logger.info("No eval set for OOT PSI calculation")
1371
+ return
1372
+ if validated_X[date_column].nunique() <= 1:
1373
+ self.logger.warning("Constant date for OOT PSI calculation")
1374
+ return
1375
+ if self.cv is not None and self.cv.is_time_series():
1376
+ self.logger.warning("Time series CV is not supported for OOT PSI calculation")
1382
1377
  return
1383
1378
 
1384
1379
  cat_features_from_backend = self.__get_categorical_features()
1380
+ cat_features_from_backend = [self.fit_columns_renaming.get(c, c) for c in cat_features_from_backend]
1385
1381
  client_cat_features, search_keys_for_metrics = self._get_and_validate_client_cat_features(
1386
1382
  estimator, validated_X, search_keys
1387
1383
  )
@@ -1390,13 +1386,13 @@ class FeaturesEnricher(TransformerMixin):
1390
1386
  cat_features_from_backend = [
1391
1387
  c
1392
1388
  for c in cat_features_from_backend
1393
- if self.fit_columns_renaming.get(c, c) not in self.id_columns_encoder.feature_names_in_
1389
+ if c not in self.id_columns_encoder.feature_names_in_
1394
1390
  ]
1395
1391
  if client_cat_features:
1396
1392
  client_cat_features = [
1397
1393
  c
1398
1394
  for c in client_cat_features
1399
- if self.fit_columns_renaming.get(c, c) not in self.id_columns_encoder.feature_names_in_
1395
+ if c not in self.id_columns_encoder.feature_names_in_
1400
1396
  ]
1401
1397
 
1402
1398
  prepared_data = self._prepare_data_for_metrics(
@@ -1431,20 +1427,6 @@ class FeaturesEnricher(TransformerMixin):
1431
1427
  eval_set_dates,
1432
1428
  ) = prepared_data
1433
1429
 
1434
- # rename cat_features
1435
- if client_cat_features:
1436
- for new_c, old_c in columns_renaming.items():
1437
- if old_c in client_cat_features:
1438
- client_cat_features.remove(old_c)
1439
- client_cat_features.append(new_c)
1440
- for cat_feature in client_cat_features:
1441
- if cat_feature not in fitting_X.columns:
1442
- self.logger.error(
1443
- f"Client cat_feature `{cat_feature}` not found in" f" x columns: {fitting_X.columns.to_list()}"
1444
- )
1445
- else:
1446
- client_cat_features = []
1447
-
1448
1430
  model_task_type = self.model_task_type or define_task(y_sorted, has_date, self.logger, silent=True)
1449
1431
  cat_features = list(set(client_cat_features + cat_features_from_backend))
1450
1432
 
@@ -1496,14 +1478,6 @@ class FeaturesEnricher(TransformerMixin):
1496
1478
  # Find latest eval set or earliest if all eval sets are before train set
1497
1479
  date_column = self._get_date_column(search_keys)
1498
1480
 
1499
- if (
1500
- date_column is None
1501
- or not eval_set
1502
- or not eval_set_dates
1503
- or (self.cv is not None and self.cv.is_time_series())
1504
- ):
1505
- return []
1506
-
1507
1481
  # Get minimum date from main dataset X
1508
1482
  main_min_date = X[date_column].min()
1509
1483
 
@@ -1757,7 +1731,7 @@ class FeaturesEnricher(TransformerMixin):
1757
1731
  def _get_and_validate_client_cat_features(
1758
1732
  self, estimator: Optional[Any], X: pd.DataFrame, search_keys: Dict[str, SearchKey]
1759
1733
  ) -> Tuple[Optional[List[str]], List[str]]:
1760
- cat_features = None
1734
+ cat_features = []
1761
1735
  search_keys_for_metrics = []
1762
1736
  if (
1763
1737
  estimator is not None
@@ -1926,7 +1900,7 @@ class FeaturesEnricher(TransformerMixin):
1926
1900
  fitting_X, y_sorted, search_keys, self.model_task_type, sort_all_columns=True, logger=self.logger
1927
1901
  )
1928
1902
  fitting_X = fitting_X[fitting_x_columns]
1929
- fitting_X, _ = self._encode_id_columns(fitting_X, self.fit_columns_renaming)
1903
+ fitting_X, _ = self._encode_id_columns(fitting_X)
1930
1904
  self.logger.info(f"Final sorted list of fitting X columns: {fitting_x_columns}")
1931
1905
  fitting_enriched_x_columns = fitting_enriched_X.columns.to_list()
1932
1906
  fitting_enriched_x_columns = sort_columns(
@@ -1938,7 +1912,7 @@ class FeaturesEnricher(TransformerMixin):
1938
1912
  logger=self.logger,
1939
1913
  )
1940
1914
  fitting_enriched_X = fitting_enriched_X[fitting_enriched_x_columns]
1941
- fitting_enriched_X, _ = self._encode_id_columns(fitting_enriched_X, self.fit_columns_renaming)
1915
+ fitting_enriched_X, _ = self._encode_id_columns(fitting_enriched_X)
1942
1916
  self.logger.info(f"Final sorted list of fitting enriched X columns: {fitting_enriched_x_columns}")
1943
1917
  date_column = self._get_date_column(search_keys)
1944
1918
  eval_set_dates = {}
@@ -1970,8 +1944,8 @@ class FeaturesEnricher(TransformerMixin):
1970
1944
  .astype(np.float64)
1971
1945
  )
1972
1946
 
1973
- fitting_eval_X, unknown_dict = self._encode_id_columns(fitting_eval_X, self.fit_columns_renaming)
1974
- fitting_enriched_eval_X, _ = self._encode_id_columns(fitting_enriched_eval_X, self.fit_columns_renaming)
1947
+ fitting_eval_X, unknown_dict = self._encode_id_columns(fitting_eval_X)
1948
+ fitting_enriched_eval_X, _ = self._encode_id_columns(fitting_enriched_eval_X)
1975
1949
 
1976
1950
  if len(unknown_dict) > 0:
1977
1951
  print(self.bundle.get("unknown_id_column_value_in_eval_set").format(unknown_dict))
@@ -3205,7 +3179,7 @@ if response.status_code == 200:
3205
3179
  is_numeric_dtype(df[self.TARGET_NAME])
3206
3180
  and self.model_task_type in [ModelTaskType.BINARY, ModelTaskType.MULTICLASS]
3207
3181
  and has_date
3208
- and not self.cv.is_time_series()
3182
+ and (self.cv is None or not self.cv.is_time_series())
3209
3183
  ):
3210
3184
  self._validate_PSI(df.sort_values(by=maybe_date_column))
3211
3185
 
@@ -3238,8 +3212,7 @@ if response.status_code == 200:
3238
3212
  self.fit_generated_features = [f for f in self.fit_generated_features if f not in self.fit_dropped_features]
3239
3213
 
3240
3214
  # Group columns should have normalized names
3241
- self.cv = None
3242
- self.__adjust_cv(df)
3215
+ self.__adjust_cv(df, force=True)
3243
3216
  if self.id_columns is not None and self.cv is not None and self.cv.is_time_series():
3244
3217
  id_columns = self.__get_renamed_id_columns()
3245
3218
  if id_columns:
@@ -3544,19 +3517,21 @@ if response.status_code == 200:
3544
3517
  reverse_renaming = {v: k for k, v in renaming.items()}
3545
3518
  return None if self.id_columns is None else [reverse_renaming.get(c) or c for c in self.id_columns]
3546
3519
 
3547
- def __adjust_cv(self, df: pd.DataFrame):
3520
+ def __adjust_cv(self, df: pd.DataFrame, force: bool = False):
3521
+ if self.cv is not None and not force:
3522
+ return
3523
+
3548
3524
  date_column = SearchKey.find_key(self.fit_search_keys, [SearchKey.DATE, SearchKey.DATETIME])
3549
3525
  # Check Multivariate time series
3550
3526
  if (
3551
- self.cv is None
3552
- and date_column
3527
+ date_column
3553
3528
  and self.model_task_type == ModelTaskType.REGRESSION
3554
3529
  and len({SearchKey.PHONE, SearchKey.EMAIL, SearchKey.HEM}.intersection(self.fit_search_keys.keys())) == 0
3555
3530
  and is_blocked_time_series(df, date_column, list(self.fit_search_keys.keys()) + [TARGET])
3556
3531
  ):
3557
3532
  msg = self.bundle.get("multivariate_timeseries_detected")
3558
3533
  self.__override_cv(CVType.blocked_time_series, msg, print_warning=False)
3559
- elif self.cv is None and self.model_task_type != ModelTaskType.REGRESSION:
3534
+ elif self.model_task_type != ModelTaskType.REGRESSION:
3560
3535
  msg = self.bundle.get("group_k_fold_in_classification")
3561
3536
  self.__override_cv(CVType.group_k_fold, msg, print_warning=self.cv is not None)
3562
3537
  group_columns = self._get_group_columns(df, self.fit_search_keys)
@@ -3594,39 +3569,32 @@ if response.status_code == 200:
3594
3569
  def _encode_id_columns(
3595
3570
  self,
3596
3571
  X: pd.DataFrame,
3597
- columns_renaming: Optional[Dict[str, str]] = None,
3598
3572
  ) -> Tuple[pd.DataFrame, Dict[str, List[Any]]]:
3599
- columns_renaming = columns_renaming or {}
3600
3573
  unknown_dict = {}
3601
3574
 
3602
3575
  if self.id_columns and self.id_columns_encoder is not None:
3603
- inverse_columns_renaming = {v: k for k, v in columns_renaming.items()}
3604
- renamed_id_columns = [
3605
- inverse_columns_renaming.get(col, col) for col in self.id_columns_encoder.feature_names_in_
3606
- ]
3607
- self.logger.info(f"Convert id columns to int: {renamed_id_columns}")
3608
- encoded = self.id_columns_encoder.transform(X[renamed_id_columns].rename(columns=columns_renaming))
3609
- for i, c in enumerate(renamed_id_columns):
3610
- unknown_values = X[encoded[:, i] == -1][c].unique().tolist()
3611
- if len(unknown_values) > 0:
3612
- unknown_dict[c] = unknown_values
3613
- X[renamed_id_columns] = encoded
3614
- X = X.loc[(X[renamed_id_columns] != -1).all(axis=1)]
3615
-
3616
- if len(unknown_dict) > 0:
3617
- self.logger.warning(f"Unknown values in id columns: {unknown_dict}")
3576
+ encoding_id_columns = [c for c in self.id_columns if c in X.columns]
3577
+ if len(encoding_id_columns) > 0:
3578
+ self.logger.info(f"Convert id columns to int: {encoding_id_columns}")
3579
+ encoded = self.id_columns_encoder.transform(X[encoding_id_columns])
3580
+ for i, c in enumerate(encoding_id_columns):
3581
+ unknown_values = X[encoded[:, i] == -1][c].unique().tolist()
3582
+ if len(unknown_values) > 0:
3583
+ unknown_dict[c] = unknown_values
3584
+ X[encoding_id_columns] = encoded
3585
+ X = X.loc[(X[encoding_id_columns] != -1).all(axis=1)]
3586
+
3587
+ if len(unknown_dict) > 0:
3588
+ self.logger.warning(f"Unknown values in id columns: {unknown_dict}")
3618
3589
 
3619
3590
  return X, unknown_dict
3620
3591
 
3621
- def _decode_id_columns(self, X: pd.DataFrame, columns_renaming: Dict[str, str]):
3622
- columns_renaming = columns_renaming or {}
3592
+ def _decode_id_columns(self, X: pd.DataFrame):
3623
3593
  if self.id_columns and self.id_columns_encoder is not None:
3624
- inverse_columns_renaming = {v: k for k, v in columns_renaming.items()}
3625
- renamed_id_columns = [
3626
- inverse_columns_renaming.get(col, col) for col in self.id_columns_encoder.feature_names_in_
3627
- ]
3628
- decoded = self.id_columns_encoder.inverse_transform(X[renamed_id_columns].rename(columns=columns_renaming))
3629
- X[renamed_id_columns] = decoded
3594
+ decoding_id_columns = [c for c in self.id_columns if c in X.columns]
3595
+ if len(decoding_id_columns) > 0:
3596
+ decoded = self.id_columns_encoder.inverse_transform(X[self.id_columns])
3597
+ X[self.id_columns] = decoded
3630
3598
 
3631
3599
  return X
3632
3600
 
@@ -4172,7 +4140,7 @@ if response.status_code == 200:
4172
4140
  columns_to_sort = [date_column] if date_column is not None else []
4173
4141
 
4174
4142
  do_sorting = True
4175
- if self.id_columns and self.cv.is_time_series():
4143
+ if self.id_columns and self.cv is not None and self.cv.is_time_series():
4176
4144
  # Check duplicates by date and id_columns
4177
4145
  reversed_columns_renaming = {v: k for k, v in columns_renaming.items()}
4178
4146
  renamed_id_columns = [reversed_columns_renaming.get(c, c) for c in self.id_columns]
@@ -1 +0,0 @@
1
- __version__ = "1.2.113a3"
File without changes
File without changes
File without changes
File without changes
File without changes