Rename column in dataframe that contains digits in the middle

Viewed 203

Say I have a dataframe columns as such df.info():

 #   Column                       Non-Null Count  Dtype 
---  ------                       --------------  ----- 
 0   Action_3.@source             1 non-null      object
 1   Description_3.#text          1 non-null      object
 2   Code_3.@source               1 non-null      object
 3   Others                       1 non-null      object
 4   Animal_1                     1 non-null      object

To:

 #   Column                       Non-Null Count  Dtype 
---  ------                       --------------  ----- 
 0   Action.@source_3             1 non-null      object
 1   Description.#text_3          1 non-null      object
 2   Code.@source_3               1 non-null      object
 3   Others                       1 non-null      object
 4   Animal_1                     1 non-null      object

This need to be done dynamically. My plan is:

  1. Use regex to find digits in the MIDDLE of string.
  2. Replace _{digit} to the back of the column name, iteratively.

My current code :

def check_number_in_column(column_name):

    return any(i.isdigit() for i in column_name)


# List out the column names then loop
temp_column_name = temp_df.columns

for j, name in enumerate(temp_column_name):            

    if check_number_in_column(name) is True :
    #TODO
1 Answers

You could use a regular expression, with pandas' str.replace to dynamically change it :

df = pd.DataFrame(
    [],
    columns=[
        "Action_3.@source",
        "Description_3.#text",
        "Code_3.@source",
        "Others",
        "Animal_1",
    ],
)

pat = r"(?P<first>.+)(?P<middle>_\d)(?P<last>.+)"
repl = lambda m: f"{m.group('first')}{m.group('last')}{m.group('middle')}"

df.columns.str.replace(pat, repl)

Index(['Action.@source_3', 'Description.#text_3', 'Code.@source_3', 'Others',
       'Animal_1'],
      dtype='object')

You can also define the function, if you wish to avoid lambda :

def repl(m):
    return f"{m.group('first')}{m.group('last')}{m.group('middle')}"

Apply the function :

df.columns.str.replace(pat, repl=repl)
Related