枚举具有相同前缀的列 [英] Enumerate columns with same prefix
问题描述
假设我们有以下简化数据:
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
我想枚举具有相同前缀的列.在这种情况下,前缀为Data, Text
.因此,预期的输出将是:
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
请注意列举的列.
尝试的解决方案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']
尝试的解决方案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']
问题:是否有更简单的解决方案,我也查看了df.filter(like='Data')
等.但这看起来也很牵强.
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问题
只要确保我没有陷入 XY问题.我想使用 pd.wide_to_long
,但是stubnames
列需要加一个数字后缀,以使数据框融化.
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.
从文档中引用:
具有存根名称['A','B']的情况下,该函数希望找到一组或多组格式为A-后缀1,A-后缀2,…,B-后缀1,B-后缀2,
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.
推荐答案
想法是将具有相同前缀的列分组,并为它们建立一个累加器.
The idea is to group columns with the same prefix, and establish a cumcount for them.
由于我们需要分别处理不带前缀的列,因此需要使用GroupBy.cumcount
和np.where
分两步来完成:
Since we need to handle column without a prefix separately, we will need to do this in two steps using GroupBy.cumcount
and np.where
:
cols = df.columns.str.split('_').str[0].to_series()
df.columns = np.where(
cols.groupby(level=0).transform('count') > 1,
cols.groupby(level=0).cumcount().add(1).astype(str).radd(df.columns),
cols
)
df
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
一个更简单的解决方案是将您不想添加后缀的列设置为索引.然后,您可以简单地做
A simpler solution would be to set columns you don't want to add a suffix to as the index. Then you can simply do
df.set_index(['A', 'B'], inplace=True)
df.columns = (
df.columns.str.split('_')
.str[0]
.to_series()
.groupby(level=0)
.cumcount()
.add(1)
.astype(str)
.radd(df.columns))
df
Data_mean1 Data_std2 Data_corr3 Text_one1 Text_two2 Text_three3
A B
a e 1 5 9 foo bar bar
b f 2 6 10 bar foo bar
c g 3 7 11 foobar barfoo barbar
d h 4 8 12 barfoo foobar foofoo
这篇关于枚举具有相同前缀的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!