diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index ff3879018674e..0b000363b5988 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -7190,6 +7190,63 @@ def __invert__(self) -> Index: # GH#8875 return self._unary_method(operator.inv) + # -------------------------------------------------------------------- + # String Case Conversion Methods + + def to_snake_case(self): + """ + Convert index labels to snake_case. + + Returns + ------- + Index + A new Index with labels converted to snake_case. + + Notes + ----- + This method uses the `inflection.underscore` function to perform the + conversion. Non-string values in the index are left unchanged. + + Examples + -------- + >>> idx = pd.Index(["ColumnName", "AnotherColumn", 123]) + >>> idx.to_snake_case() + Index(['column_name', 'another_column', 123], dtype='object') + """ + from inflection import underscore + + return self.map( + lambda x: underscore(x.replace(" ", "_")) if isinstance(x, str) else x + ) + + def to_camel_case(self): + """ + Convert index labels to camelCase. + + Returns + ------- + Index + A new Index with labels converted to camelCase. + + Notes + ----- + This method uses the `inflection.camelize` function to perform the + conversion. Non-string values in the index are left unchanged. + + Examples + -------- + >>> idx = pd.Index(["column_name", "another_column", 123]) + >>> idx.to_camel_case() + Index(['columnName', 'anotherColumn', 123], dtype='object') + """ + from inflection import camelize + + return self.map( + lambda x: camelize(x.replace(" ", "_"), uppercase_first_letter=False) + if isinstance(x, str) + else x + ) + # -------------------------------------------------------------------- # Reductions diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 5b75bd9afd6df..5dedbe165f774 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -1350,6 +1350,38 @@ def test_index_round(self, decimals, expected_results): tm.assert_index_equal(result, expected) + @pytest.mark.parametrize( + "input_labels, expected_snake_case", + [ + ( + ["ColumnName", "AnotherColumn", 123], + ["column_name", "another_column", 123], + ), + (["MixedCase", "with spaces", None], ["mixed_case", "with_spaces", None]), + ], + ) + def test_to_snake_case(self, input_labels, expected_snake_case): + idx = Index(input_labels) + result = idx.to_snake_case() + expected = Index(expected_snake_case) + tm.assert_index_equal(result, expected) + + @pytest.mark.parametrize( + "input_labels, expected_camel_case", + [ + ( + ["column_name", "another_column", 123], + ["columnName", "anotherColumn", 123], + ), + (["with_spaces", "Mixed_Case", None], ["withSpaces", "mixedCase", None]), + ], + ) + def test_to_camel_case(self, input_labels, expected_camel_case): + idx = Index(input_labels) + result = idx.to_camel_case() + expected = Index(expected_camel_case) + tm.assert_index_equal(result, expected) + class TestMixedIntIndex: # Mostly the tests from common.py for which the results differ