Selecting columns with startswith in pandas

Viewed 2553

Hi I have a data and I want to rename one of the column and select columns starts with t string.

raw_data = {'patient': [1, 1, 1, 2, 2],
        'obs': [1, 2, 3, 1, 2],
        'treatment': [0, 1, 0, 1, 0],
        'score': ['strong', 'weak', 'normal', 'weak', 'strong'],    
        'tr': [1,2,3,4,5],
        'tk': [6,7,8,9,10],
        'ak': [11,12,13,14,15]

        }
df = pd.DataFrame(raw_data, columns = ['patient', 'obs', 'treatment', 'score','tr','tk','ak'])

df

   patient  obs  treatment   score  tr  tk  ak
0        1    1          0  strong   1   6  11
1        1    2          1    weak   2   7  12
2        1    3          0  normal   3   8  13
3        2    1          1    weak   4   9  14
4        2    2          0  strong   5  10  15

So I tried by following python-pandas-renaming-column-name-startswith

df.rename(columns = {'treatment':'treat'})[['score','obs',df[df.columns[pd.Series(df.columns).str.startswith('t')]]]]

but getting this error

TypeError: 'DataFrame' objects are mutable, thus they cannot be hashed

How can I select the columns that starts with t ?

Thx

2 Answers

Convert to Series is not necessary, but if want add to another list of columns convert output to list:

cols =  df.columns[df.columns.str.startswith('t')].tolist()

df = df[['score','obs'] + cols].rename(columns = {'treatment':'treat'})

Another idea is use 2 masks and chain by | for bitwise OR:

Notice:

Columns names are filtered from original columns names before rename in your solution, so is necessary rename later.

m1 = df.columns.str.startswith('t')
m2 = df.columns.isin(['score','obs'])

df = df.loc[:, m1 | m2].rename(columns = {'treatment':'treat'})
print (df)
   obs  treat   score  tr  tk
0    1      0  strong   1   6
1    2      1    weak   2   7
2    3      0  normal   3   8
3    1      1    weak   4   9
4    2      0  strong   5  10

If need rename first, is necessary reassign back for filter by renamed columns names:

df = df.rename(columns = {'treatment':'treat'})
df = df.loc[:, df.columns.str.startswith('t') | df.columns.isin(['score','obs'])] 
#Select columns startswith "t"
df = df[df.columns[df.columns.str.startswith('t')]]

#Rename your column
df.rename(columns = {'treatment':'treat'})
Related