Skip to content

Commit 1f66f1a

Browse files
committed
Merge branch 'release/14.7'
2 parents bd1f4d1 + d092039 commit 1f66f1a

20 files changed

Lines changed: 126 additions & 33 deletions

‎HISTORY.txt‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@ Changelog
22
==========
33

44

5+
14.7.3 (2026-08-03)
6+
-------------------
7+
8+
* Initial release for DSS 14.7.3
9+
10+
14.7.2 (2026-07-13)
11+
-------------------
12+
13+
* Initial release for DSS 14.7.2
14+
15+
14.7.1 (2026-07-13)
16+
-------------------
17+
18+
* Initial release for DSS 14.7.1
19+
20+
14.7.0 (2026-06-25)
21+
-------------------
22+
23+
* Initial release for DSS 14.7.0
24+
525
14.6.2 (2026-06-15)
626
-------------------
727

‎dataikuscoring/processors/binarize.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ def __init__(self, parameters):
1313
self.thresholds = parameters["thresholds"]
1414

1515
def process(self, X_numeric, X_non_numeric):
16-
X_numeric[:, self.output_columns] = np.where(X_numeric[:, self.columns] > self.thresholds, 1.0, 0.0)
16+
kept = [
17+
(self.columns[index], self.output_columns[index], self.thresholds[index])
18+
for index in X_numeric.existing_column_indices(self.output_columns)
19+
]
20+
if len(kept) > 0:
21+
columns, output_columns, thresholds = zip(*kept)
22+
X_numeric[:, list(output_columns)] = np.where(X_numeric[:, list(columns)] > thresholds, 1.0, 0.0)
1723
return X_numeric, X_non_numeric
1824

1925
def __repr__(self):

‎dataikuscoring/processors/cat_cat_interaction.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ def process(self, X_numeric, X_non_numeric):
1919

2020
for col1, col2, values in zip(self.column_1, self.column_2, self.values):
2121
for value_col1, value_col2 in values:
22-
mask = (data[:, columns.index(col1)] == value_col1) * (data[:, columns.index(col2)] == value_col2)
23-
X_numeric[:, "interaction:{}:{}:{}:{}".format(col1, col2, value_col1, value_col2)] = np.where(mask, 1, self.unrecorded_value)
22+
output_name = "interaction:{}:{}:{}:{}".format(col1, col2, value_col1, value_col2)
23+
if X_numeric.has_column(output_name):
24+
mask = (data[:, columns.index(col1)] == value_col1) * (data[:, columns.index(col2)] == value_col2)
25+
X_numeric[:, output_name] = np.where(mask, 1, self.unrecorded_value)
2426

2527
return X_numeric, X_non_numeric
2628

‎dataikuscoring/processors/categorical_encode.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,21 @@ def __init__(self, parameters):
2121
def process(self, X_numeric, X_non_numeric):
2222
for column, level, output_names, defaults, encodings in zip(
2323
self.columns, self.levels, self.output_names, self.defaults, self.encodings):
24+
kept_output_names = X_numeric.existing_columns(output_names)
25+
if len(kept_output_names) == 0:
26+
continue
2427

2528
mask_all = np.full((len(X_numeric),), False)
2629
for category, values in encodings.items():
2730
mask = (X_non_numeric[:, column] == category)
2831
for value, output_name in zip(values, output_names):
29-
X_numeric[mask, output_name] = value
32+
if X_numeric.has_column(output_name):
33+
X_numeric[mask, output_name] = value
3034
mask_all += mask
3135

3236
for default, output_name in zip(defaults, output_names):
33-
X_numeric[~mask_all, output_name] = default
37+
if X_numeric.has_column(output_name):
38+
X_numeric[~mask_all, output_name] = default
3439

3540
return X_numeric, X_non_numeric
3641

‎dataikuscoring/processors/datetime_cyclical.py‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,21 @@ def truncate_datetime(self, period, date):
3232
def process(self, X_numeric, X_non_numeric):
3333
origin = datetime.datetime(1900, 1, 1, 0, 0, 0)
3434
for column, periods in self.mapping.items():
35+
output_names_by_period = {}
36+
for period in periods:
37+
prefix = "datetime_cyclical:{}:{}:".format(column, period.lower())
38+
output_names_by_period[period] = (prefix + "sin", prefix + "cos")
39+
3540
timestamps = X_numeric[:, column] * 1000.0
3641
dates = [origin + datetime.timedelta(milliseconds=timestamp) for timestamp in timestamps]
37-
3842
for period in periods:
43+
sin_output_name, cos_output_name = output_names_by_period[period]
3944
second_subperiods = np.array([(date - self.truncate_datetime(period, date)).total_seconds() for date in dates])
4045
trigo_args = second_subperiods * 2 * 3.141592653589793 / PERIOD[period]
41-
prefix = "datetime_cyclical:{}:{}:".format(column, period.lower())
42-
X_numeric[:, prefix + "sin"] = np.sin(trigo_args)
43-
X_numeric[:, prefix + "cos"] = np.cos(trigo_args)
46+
if X_numeric.has_column(sin_output_name):
47+
X_numeric[:, sin_output_name] = np.sin(trigo_args)
48+
if X_numeric.has_column(cos_output_name):
49+
X_numeric[:, cos_output_name] = np.cos(trigo_args)
4450

4551
return X_numeric, X_non_numeric
4652

‎dataikuscoring/processors/derive.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ def __init__(self, parameters):
2828
def process(self, X_numeric, X_non_numeric):
2929
for i, column in enumerate(self.columns):
3030
# Propagate NaN with default 0 * X_numeric[:, column]
31-
X_numeric[:, self.log_names[i]] = np.where(X_numeric[:, column] > 0, np.log(X_numeric[:, column] + 0.00000001), 0 * X_numeric[:, column])
32-
X_numeric[:, self.sqrt_names[i]] = np.where(X_numeric[:, column] > 0, np.sqrt(X_numeric[:, column]), 0 * X_numeric[:, column])
33-
X_numeric[:, self.square_names[i]] = X_numeric[:, column] ** 2
31+
if X_numeric.has_column(self.log_names[i]):
32+
X_numeric[:, self.log_names[i]] = np.where(X_numeric[:, column] > 0, np.log(X_numeric[:, column] + 0.00000001), 0 * X_numeric[:, column])
33+
if X_numeric.has_column(self.sqrt_names[i]):
34+
X_numeric[:, self.sqrt_names[i]] = np.where(X_numeric[:, column] > 0, np.sqrt(X_numeric[:, column]), 0 * X_numeric[:, column])
35+
if X_numeric.has_column(self.square_names[i]):
36+
X_numeric[:, self.square_names[i]] = X_numeric[:, column] ** 2
3437

3538
return X_numeric, X_non_numeric
3639

‎dataikuscoring/processors/drop_rows.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def compute_valid_mask(self, X_numeric, X_non_numeric):
1616
for column in self.columns:
1717
# important to check in non numeric first because dates can be in both
1818
# but are not normalized yet
19-
if column in X_non_numeric.column_index:
19+
if X_non_numeric.has_column(column):
2020
rows_to_compute *= np.where(X_non_numeric[:, column] == None, False, True)
2121
else:
2222
rows_to_compute *= np.where(np.isnan(X_numeric[:, column]), False, True)

‎dataikuscoring/processors/dummify.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,23 @@ def process(self, X_numeric, X_non_numeric):
1717
mask_in_levels = np.full((len(X_numeric,)), False)
1818
for value in parameters["levels"]:
1919
mask = X_non_numeric[:, column] == value
20-
X_numeric[:, "dummy:{}:{}".format(column, value)] = np.where(mask, 1, self.unrecorded_value)
20+
output_name = "dummy:{}:{}".format(column, value)
21+
if X_numeric.has_column(output_name):
22+
X_numeric[:, output_name] = np.where(mask, 1, self.unrecorded_value)
2123
mask_in_levels += mask
2224

2325
# Missing values
2426
mask_none = X_non_numeric[:, column] == None
25-
X_numeric[:, "dummy:{}:N/A".format(column)] = np.where(mask_none, 1, self.unrecorded_value)
27+
output_name = "dummy:{}:N/A".format(column)
28+
if X_numeric.has_column(output_name):
29+
X_numeric[:, output_name] = np.where(mask_none, 1, self.unrecorded_value)
2630

2731
# Values unseen during training
2832
if parameters["with_others"]:
2933
mask_others = ~(mask_none + mask_in_levels)
30-
X_numeric[:, "dummy:{}:{}".format(column, "__Others__")] = np.where(mask_others, 1, self.unrecorded_value)
34+
output_name = "dummy:{}:{}".format(column, "__Others__")
35+
if X_numeric.has_column(output_name):
36+
X_numeric[:, output_name] = np.where(mask_others, 1, self.unrecorded_value)
3137
return X_numeric, X_non_numeric
3238

3339
def __repr__(self):

‎dataikuscoring/processors/flag.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ def __init__(self, parameters):
1414
self.unrecorded_value = parameters["unrecorded_value"]
1515

1616
def process(self, X_numeric, X_non_numeric):
17-
for (column, output_name) in zip(self.columns, self.output_names):
18-
if column in X_numeric.column_index:
19-
X_numeric[:, output_name] = np.where(np.isnan(X_numeric[:, column]), self.unrecorded_value, 1)
17+
for input_column, output_feature_name in zip(self.columns, self.output_names):
18+
if not X_numeric.has_column(output_feature_name):
19+
# Feature reduction may drop this generated output feature, so there is no allocated column to write.
20+
continue
21+
if X_numeric.has_column(input_column):
22+
X_numeric[:, output_feature_name] = np.where(np.isnan(X_numeric[:, input_column]), self.unrecorded_value, 1)
2023
else:
21-
X_numeric[:, output_name] = np.where(X_non_numeric[:, column] == None, self.unrecorded_value, 1)
24+
# Non-numeric input columns live in X_non_numeric; their generated flag output is numeric.
25+
X_numeric[:, output_feature_name] = np.where(X_non_numeric[:, input_column] == None, self.unrecorded_value, 1)
2226

2327
return X_numeric, X_non_numeric
2428

‎dataikuscoring/processors/impute.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def __init__(self, parameters):
1818
def process(self, X_numeric, X_non_numeric):
1919
for column, impute_value in self.impute_values.items():
2020
# Important to check on non numeric first since it can be in both (and not encoded at this step)
21-
if column in X_non_numeric.column_index:
21+
if X_non_numeric.has_column(column):
2222
X_non_numeric[:, column] = np.where(X_non_numeric[:, column] == None, impute_value, X_non_numeric[:, column])
2323
else:
2424
X_numeric[:, column] = np.where(np.isnan(X_numeric[:, column]), impute_value, X_numeric[:, column])

0 commit comments

Comments
 (0)