From 53cb6e856440c3d8172839f2330bcae5daf4125b Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:42:13 -0700 Subject: [PATCH 1/3] fix(pandas list): deal with cellids with inconsistent types --- autotest/test_binaryfile.py | 2 +- flopy/mf6/data/mfdataplist.py | 137 ++++++++++++++++++++++++++-------- 2 files changed, 108 insertions(+), 31 deletions(-) diff --git a/autotest/test_binaryfile.py b/autotest/test_binaryfile.py index b5cfc65bc..2a2718328 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 b0d921bf9..bdb9858fe 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) From a23533018ba8b12f0f4a334df14cfbd22f592f12 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 6 Oct 2023 08:03:52 -0700 Subject: [PATCH 2/3] feat(pandas list): handle list size of 0 correctly --- flopy/mf6/mfpackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flopy/mf6/mfpackage.py b/flopy/mf6/mfpackage.py index f25900614..747f1f691 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() From cbf2d0ca767ddf2be6fb139b444fcbcd5fabcc9c Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 6 Oct 2023 10:08:13 -0700 Subject: [PATCH 3/3] feat(pandas list): fix for handling special case where boundname set but not used --- flopy/mf6/data/mfdataplist.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flopy/mf6/data/mfdataplist.py b/flopy/mf6/data/mfdataplist.py index bdb9858fe..508c3412f 100644 --- a/flopy/mf6/data/mfdataplist.py +++ b/flopy/mf6/data/mfdataplist.py @@ -549,6 +549,12 @@ def _resolve_columns(self, data): if len(data[0]) == len(self._data_item_names): return self._data_item_names, True + if ( + len(data[0]) == len(self._header_names) - 1 + and self._header_names[-1] == "boundname" + ): + return self._header_names[:-1], True + if ( len(data[0]) == len(self._data_item_names) - 1 and self._data_item_names[-1] == "boundname"