Repository: alteryx/woodwork (python)

Issue:
Renaming columns switches the schema column order
When renaming woodwork columns the order of columns in the schema also changes. Is this intended behavior?

```python
df = pd.DataFrame({"A": [1, 2, 3], "B": [1, 2, 3], "C": [1, 2, 3]})
df.ww.init()

df_renamed = df.ww.rename(rename)

assert df_renamed.ww.schema.columns == df.ww.schema.columns
```


Pull request description:
Preserve schema order with rename
fix #1588 

fyi @jeremyliweishih 

Patch:
diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst
index 983a35f..99a849a 100644
--- a/docs/source/release_notes.rst
+++ b/docs/source/release_notes.rst
@@ -8,13 +8,14 @@ Future Release
     * Enhancements
     * Fixes
         * Fix importlib DeprecationWarning in ``inference_functions.py`` (:pr:`1584`)
+        * Schema now maintains column order after renaming a column (:pr:`1594`)
     * Changes
         * Rename `backup_dtype` to `pyspark_dtype` (:pr:`1593`)
     * Documentation Changes
     * Testing Changes
 
     Thanks to the following people for contributing to this release:
-    :user:`sbadithe`
+    :user:`sbadithe`, :user:`bchen1116`
 
 v0.21.0 December 1, 2022
 ========================
diff --git a/woodwork/table_schema.py b/woodwork/table_schema.py
index 5eb6c81..0a58521 100644
--- a/woodwork/table_schema.py
+++ b/woodwork/table_schema.py
@@ -1,4 +1,5 @@
 import copy
+from collections import OrderedDict
 from collections.abc import Hashable
 
 import pandas as pd
@@ -444,9 +445,12 @@ class TableSchema(object):
             raise ValueError("New columns names must be unique from one another.")
 
         new_schema = copy.deepcopy(self)
+        ordered_col_dict = OrderedDict()
+        for column in self.columns:
+            ordered_col_dict[column] = columns.get(column, column)
 
         cols_to_update = {}
-        for old_name, new_name in columns.items():
+        for old_name, new_name in ordered_col_dict.items():
             col = new_schema.columns.pop(old_name)
             cols_to_update[new_name] = col
 


Test patch:
diff --git a/woodwork/tests/accessor/test_table_accessor.py b/woodwork/tests/accessor/test_table_accessor.py
index ad87fbb..ad56f74 100644
--- a/woodwork/tests/accessor/test_table_accessor.py
+++ b/woodwork/tests/accessor/test_table_accessor.py
@@ -2312,11 +2312,17 @@ def test_accessor_rename(sample_df):
     )
     original_df = sample_df.ww.copy()
 
-    new_df = sample_df.ww.rename({"age": "birthday"})
+    rename_dict = {"age": "birthday"}
+    new_df = sample_df.ww.rename(rename_dict)
 
-    assert to_pandas(sample_df.rename(columns={"age": "birthday"})).equals(
+    assert to_pandas(sample_df.rename(columns=rename_dict)).equals(
         to_pandas(new_df),
     )
+    expected_schema_order = [
+        rename_dict.get(name, name) for name in list(sample_df.columns)
+    ]
+    assert list(new_df.ww.schema.columns.keys()) == expected_schema_order
+
     # Confirm original dataframe hasn't changed
     assert to_pandas(sample_df).equals(to_pandas(original_df))
     assert sample_df.ww.schema == original_df.ww.schema
diff --git a/woodwork/tests/schema/test_table_schema.py b/woodwork/tests/schema/test_table_schema.py
index 935f99c..992c5fb 100644
--- a/woodwork/tests/schema/test_table_schema.py
+++ b/woodwork/tests/schema/test_table_schema.py
@@ -1337,3 +1337,19 @@ def test_validation_methods_called(
     no_validation_schema.set_time_index("signup_date", validate=True)
     assert mock_check_time_index.called
     assert validation_schema == no_validation_schema
+
+
+def test_schema_rename_preserves_order(
+    sample_column_names,
+    sample_inferred_logical_types,
+):
+    schema = TableSchema(
+        sample_column_names,
+        sample_inferred_logical_types,
+    )
+    rename_dict = {"id": "renamed_index", "signup_date": "renamed_time_index"}
+    renamed_schema = schema.rename(rename_dict)
+    expected_result = [
+        rename_dict.get(col_name, col_name) for col_name in sample_column_names
+    ]
+    assert list(renamed_schema.columns.keys()) == expected_result