Assume we have the following simplified data:
df = pd.DataFrame({'A':list('abcd'),
'B':list('efgh'),
'Data_mean':[1,2,3,4],
'Data_std':[5,6,7,8],
'Data_corr':[9,10,11,12],
'Text_one':['foo', 'bar', 'foobar', 'barfoo'],
'Text_two':['bar', 'foo', 'barfoo', 'foobar'],
'Text_three':['bar', 'bar', 'barbar', 'foofoo']})
A B Data_mean Data_std Data_corr Text_one Text_two Text_three
0 a e 1 5 9 foo bar bar
1 b f 2 6 10 bar foo bar
2 c g 3 7 11 foobar barfoo barbar
3 d h 4 8 12 barfoo foobar foofoo
I want to enumerate columns with the same prefix. In this case the prefixes are Data, Text. So expected output would be:
A B Data_mean1 Data_std2 Data_corr3 Text_one1 Text_two2 Text_three3
0 a e 1 5 9 foo bar bar
1 b f 2 6 10 bar foo bar
2 c g 3 7 11 foobar barfoo barbar
3 d h 4 8 12 barfoo foobar foofoo
Note the enumerated columns.
Attempted solution #1:
def enumerate_cols(dataframe, prefix):
cols = []
num = 1
for col in dataframe.columns:
if col.startswith(prefix):
cols.append(col + str(num))
num += 1
else:
cols.append(col)
return cols
enumerate_cols(df, 'Data')
['A',
'B',
'Data_mean1',
'Data_std2',
'Data_corr3',
'Text_one',
'Text_two',
'Text_three']
Attempted solution #2:
[c+str(x+1) for x, c in enumerate([col for col in df.columns if col.startswith('Data')])]
['Data_mean1', 'Data_std2', 'Data_corr3']
Question: Is there an easier solution to do this, I also looked at df.filter(like='Data') etc. But that looked also quite far fetched.
XY problem
Just be sure I didn't fall into the XY problem. I want to use pd.wide_to_long, but the stubnames columns need to be suffixed by a number to be able to melt the dataframe.
As quoted from the docs:
With stubnames [‘A’, ‘B’], this function expects to find one or more group of columns with format A-suffix1, A-suffix2,…, B-suffix1, B-suffix2,
pd.wide_to_long(df, stubnames=['Data', 'Text'], i=['A', 'B'], j='grp', sep='_')
This returns an empty dataframe.