From f77989d33955baa76032d9341226385215e45821 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 6 Oct 2023 08:38:09 -0700 Subject: [PATCH] fix(pandas list): deal with cellids with inconsistent types (#1980) * fix(pandas list): deal with cellids with inconsistent types * feat(pandas list): handle list size of 0 correctly --- autotest/test_binaryfile.py | 2 +- flopy/mf6/data/mfdataplist.py | 137 ++++++++++++++++++++++++++-------- flopy/mf6/mfpackage.py | 2 +- 3 files changed, 109 insertions(+), 32 deletions(-) diff --git a/autotest/test_binaryfile.py b/autotest/test_binaryfile.py index b5cfc65bc0..2a27183289 100644 --- a/autotest/test_binaryfile.py +++ b/autotest/test_binaryfile.py @@ -447,7 +447,7 @@ def mf6_gwf_2sp_st_tr(function_tmpdir): wel = flopy.mf6.ModflowGwfwel( model=gwf, - stress_period_data={0: 0, 1: [[(0, 0, 0), -1]]}, + stress_period_data={0: None, 1: [[(0, 0, 0), -1]]}, ) sto = flopy.mf6.ModflowGwfsto( diff --git a/flopy/mf6/data/mfdataplist.py b/flopy/mf6/data/mfdataplist.py index b0d921bf9d..bdb9858fe8 100644 --- a/flopy/mf6/data/mfdataplist.py +++ b/flopy/mf6/data/mfdataplist.py @@ -391,6 +391,29 @@ def _unique_column_name(data, col_base_name): idx += 1 return col_name + @staticmethod + def _untuple_manually(pdata, loc, new_column_name, column_name, index): + """ + Loop through pandas DataFrame removing tuples from cellid columns. + Used when pandas "insert" method to perform the same task fails. + """ + # build new column list + new_column = [] + for idx, row in pdata.iterrows(): + if isinstance(row[column_name], tuple) or isinstance( + row[column_name], list + ): + new_column.append(row[column_name][index]) + else: + new_column.append(row[column_name]) + + # insert list as new column + pdata.insert( + loc=loc, + column=new_column_name, + value=new_column, + ) + def _untuple_cellids(self, pdata): """ For all cellids in "pdata", convert them to layer, row, column fields and @@ -421,43 +444,97 @@ def _untuple_cellids(self, pdata): for field_idx, column_name in fields_to_correct: # add individual layer/row/column/cell/node columns if isinstance(self._mg, StructuredGrid): - pdata.insert( - loc=field_idx, - column=self._unique_column_name(pdata, "layer"), - value=pdata.apply(lambda x: x[column_name][0], axis=1), - ) - pdata.insert( - loc=field_idx + 1, - column=self._unique_column_name(pdata, "row"), - value=pdata.apply(lambda x: x[column_name][1], axis=1), - ) - pdata.insert( - loc=field_idx + 2, - column=self._unique_column_name(pdata, "column"), - value=pdata.apply(lambda x: x[column_name][2], axis=1), - ) + try: + pdata.insert( + loc=field_idx, + column=self._unique_column_name(pdata, "layer"), + value=pdata.apply(lambda x: x[column_name][0], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx, + self._unique_column_name(pdata, "layer"), + column_name, + 0, + ) + try: + pdata.insert( + loc=field_idx + 1, + column=self._unique_column_name(pdata, "row"), + value=pdata.apply(lambda x: x[column_name][1], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx + 1, + self._unique_column_name(pdata, "row"), + column_name, + 1, + ) + try: + pdata.insert( + loc=field_idx + 2, + column=self._unique_column_name(pdata, "column"), + value=pdata.apply(lambda x: x[column_name][2], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx + 2, + self._unique_column_name(pdata, "column"), + column_name, + 2, + ) elif isinstance(self._mg, VertexGrid): - pdata.insert( - loc=field_idx, - column=self._unique_column_name(pdata, "layer"), - value=pdata.apply(lambda x: x[column_name][0], axis=1), - ) - pdata.insert( - loc=field_idx + 1, - column=self._unique_column_name(pdata, "cell"), - value=pdata.apply(lambda x: x[column_name][1], axis=1), - ) + try: + pdata.insert( + loc=field_idx, + column=self._unique_column_name(pdata, "layer"), + value=pdata.apply(lambda x: x[column_name][0], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx, + self._unique_column_name(pdata, "layer"), + column_name, + 0, + ) + try: + pdata.insert( + loc=field_idx + 1, + column=self._unique_column_name(pdata, "cell"), + value=pdata.apply(lambda x: x[column_name][1], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx + 1, + self._unique_column_name(pdata, "cell"), + column_name, + 1, + ) elif isinstance(self._mg, UnstructuredGrid): if column_name == "node": # fixing a problem where node was specified as a tuple # make sure new column is named properly column_name = "node_2" pdata = pdata.rename(columns={"node": column_name}) - pdata.insert( - loc=field_idx, - column=self._unique_column_name(pdata, "node"), - value=pdata.apply(lambda x: x[column_name][0], axis=1), - ) + try: + pdata.insert( + loc=field_idx, + column=self._unique_column_name(pdata, "node"), + value=pdata.apply(lambda x: x[column_name][0], axis=1), + ) + except (ValueError, TypeError): + self._untuple_manually( + pdata, + field_idx, + self._unique_column_name(pdata, "node"), + column_name, + 0, + ) # remove cellid tuple pdata = pdata.drop(column_name, axis=1) return pdata, len(fields_to_correct) diff --git a/flopy/mf6/mfpackage.py b/flopy/mf6/mfpackage.py index f25900614c..747f1f6919 100644 --- a/flopy/mf6/mfpackage.py +++ b/flopy/mf6/mfpackage.py @@ -2276,7 +2276,7 @@ def _update_size_defs(self): new_size = len(dataset.get_data()) if size_def.get_data() is None: - current_size = 0 + current_size = -1 else: current_size = size_def.get_data()