Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions pysr/sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1686,11 +1686,9 @@ def _validate_and_set_fit_params(
"Using DataFrame column names instead."
)

if (
pd.api.types.is_object_dtype(X.columns)
and X.columns.str.contains(" ").any()
):
X.columns = X.columns.str.replace(" ", "_")
cols_str = X.columns.astype(str)
if cols_str.str.contains(" ").any():
X.columns = cols_str.str.replace(" ", "_")
warnings.warn(
"Spaces in DataFrame column names are not supported. "
"Spaces have been replaced with underscores. \n"
Expand Down Expand Up @@ -2560,6 +2558,19 @@ def predict(
# be correctly filtered with self.selection_mask_
X = X[X.columns[self.selection_mask_]]
X.columns = self.feature_names_in_

# During fit, we replace spaces in DataFrame column names with
# underscores. Apply the same normalization here.
cols_str = X.columns.astype(str)
if cols_str.str.contains(" ").any():
X = X.copy()
X.columns = cols_str.str.replace(" ", "_")
warnings.warn(
"Spaces in DataFrame column names are not supported. "
"Spaces have been replaced with underscores. \n"
"Please rename the columns to valid names."
)

# Without feature information, CallableEquation/lambda_format equations
# require that the column order of X matches that of the X used during
# the fitting process. _validate_data removes this feature information
Expand Down
21 changes: 21 additions & 0 deletions pysr/test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,27 @@ def test_pickle_inv_sympy_expression(self):
# Check that the same operator mapping was used (1/x for inv)
self.assertEqual(original_result, 0.5 + 3.0) # 1/2 + 3 = 3.5

def test_predict_replaces_spaces_in_dataframe_columns(self):
# Regression for #690.
model = PySRRegressor(
niterations=1,
populations=1,
procs=0,
progress=False,
verbosity=0,
temp_equation_file=True,
)

X_fit = pd.DataFrame({"a b": [1.0, 2.0], "c d": [3.0, 4.0]})
y = X_fit["a b"] + X_fit["c d"]
X_pred = X_fit.copy()

model.fit(X_fit, y)
np.testing.assert_array_equal(model.feature_names_in_, np.array(["a_b", "c_d"]))

y_pred = model.predict(X_pred)
assert np.isfinite(y_pred).all()

def test_pickle_with_temp_equation_file(self):
"""If we have a temporary equation file, unpickle the estimator."""
model = PySRRegressor(
Expand Down
Loading