diff --git a/glotaran/builtin/io/pandas/csv.py b/glotaran/builtin/io/pandas/csv.py index 77a0e6a7c..b1ce0da42 100644 --- a/glotaran/builtin/io/pandas/csv.py +++ b/glotaran/builtin/io/pandas/csv.py @@ -8,6 +8,8 @@ from glotaran.io import ProjectIoInterface from glotaran.io import register_project_io from glotaran.parameter import ParameterGroup +from glotaran.utils.io import safe_parameters_fillna +from glotaran.utils.io import safe_parameters_replace @register_project_io(["csv"]) @@ -27,8 +29,8 @@ def load_parameters(self, file_name: str) -> ParameterGroup: :class:`ParameterGroup """ df = pd.read_csv(file_name, skipinitialspace=True, na_values=["None", "none"]) - df["minimum"].fillna(-np.inf, inplace=True) - df["maximum"].fillna(np.inf, inplace=True) + safe_parameters_fillna(df, "minimum", -np.inf) + safe_parameters_fillna(df, "maximum", np.inf) return ParameterGroup.from_dataframe(df, source=file_name) def save_parameters(self, parameters: ParameterGroup, file_name: str, *, sep: str = ","): @@ -44,6 +46,6 @@ def save_parameters(self, parameters: ParameterGroup, file_name: str, *, sep: st Other separators can be used optionally. """ df = parameters.to_dataframe() - df["minimum"].replace([-np.inf], "", inplace=True) - df["maximum"].replace([np.inf], "", inplace=True) + safe_parameters_replace(df, "minimum", -np.inf, "") + safe_parameters_replace(df, "maximum", np.inf, "") df.to_csv(file_name, na_rep="None", index=False, sep=sep) diff --git a/glotaran/utils/io.py b/glotaran/utils/io.py index 5fff5ad8a..072bcb23d 100644 --- a/glotaran/utils/io.py +++ b/glotaran/utils/io.py @@ -180,3 +180,41 @@ def relative_posix_path(source_path: StrOrPath, base_path: StrOrPath | None = No if base_path is not None and os.path.isabs(source_path): source_path = os.path.relpath(source_path, Path(base_path).as_posix()) return Path(source_path).as_posix() + + +def safe_parameters_fillna(df, column_name, fill_value): + """Ensure that columns exist in order to replace empty strings with +/-np.inf values. + + Parameters + ---------- + df : pd.DataFrame + DataFrame from which specific column values will be replaced + column_name : str + Name of column from DataFrame + fill_value : str + Values to be replaced in column + """ + if column_name in df.columns: + df[column_name].fillna(fill_value, inplace=True) + + +def safe_parameters_replace(df, column_name, to_be_replaced_values, replace_value): + """Ensure that columns exist in order to replace +/-np.inf values with empty strings. + + If value is not list or tuple format, convert into list with same value as element. + + Parameters + ---------- + df : pd.DataFrame + DataFrame from which specific column values will be replaced + column_name : str + Name of column from DataFrame + to_be_replaced_values : float + Values to be replaced + replace_value : str + Replace values + """ + if not isinstance(to_be_replaced_values, (list, tuple)): + to_be_replaced_values = [to_be_replaced_values] + if column_name in df.columns: + df[column_name].replace(to_be_replaced_values, replace_value, inplace=True)