Python 将多列合并为一列

Python 将多列合并为一列,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有一个df,它有多个以相同值结尾的列。我想把这些列合并成最后一列。例如,任何以“_1”结尾的列都应该进入标记为“final_1”的新列。如果“_1”中的所有值均为“1”,则final_1中的值将为1;否则,如果“_1”列中至少有一个值不是“1”,则final_1中的值将为0 如果我的解释不正确,那么原始和最终结果数据帧将更加清晰 df = pd.DataFrame({'KEY': ['100000003', '100000009', '100000009', '100000009'],

我有一个df,它有多个以相同值结尾的列。我想把这些列合并成最后一列。例如,任何以“_1”结尾的列都应该进入标记为“final_1”的新列。如果“_1”中的所有值均为“1”,则final_1中的值将为1;否则,如果“_1”列中至少有一个值不是“1”,则final_1中的值将为0

如果我的解释不正确,那么原始和最终结果数据帧将更加清晰

df = pd.DataFrame({'KEY': ['100000003', '100000009', '100000009', '100000009'], 
              'RO_1': [1, 1, 4,1],
              'RO_2': [1, 0, 0,0],
              'RO_3': [1, 1, 1,1],
              'en_1': [1, 4, 1,1],
              'en_2': [1, 4, 1,0],
              'en_3': [1, 4, 4,0],
              'ao_1': [1, 4, 1,1],
              'ao_2': [1, 4, 1,0],
              'ao_3': [1, 4, 4,0] })

    KEY         RO_1    RO_2    RO_3    ao_1    ao_2    ao_3    en_1    en_2    en_3
0   100000003   1       1       1       1       1       1       1       1       1
2   100000009   4       0       1       1       1       4       1       1       4
3   100000009   1       0       1       1       0       0       1       0       0
最终结果:

   KEY          RO_1    RO_2    RO_3    ao_1    ao_2    ao_3    en_1    en_2    en_3  Final1  Final2  Final3
0   100000003   1       1       1       1       1       1       1       1       1     1       1       1
2   100000009   4       0       1       1       1       4       1       1       4     0       0       0
3   100000009   1       0       1       1       0       0       1       0       0     1       0       0
我目前的尝试。因为有3个不同的列,所以我使用循环。然后,我将原始df与新帧(mc)相结合。但是我没有得到任何不同

for i in range(1,4):
    mc = df.filter(regex='^_' + str(i)).isin([1]).astype(int).rename(columns=lambda x: x.replace('_', 'Final'))
df= pd.concat([df, mc], axis=1)

@DSM提出了一个更好的拆分列名的选项:

In [170]: cols = df.columns.drop('KEY')

In [171]: d = (df[cols]
                 .groupby(cols.str.split('_').str[-1], axis=1)
                 .all()
                 .astype(int)
                 .add_prefix('Final_'))

In [172]: df.join(d)
Out[172]:
         KEY  RO_1  RO_2  RO_3  ao_1  ao_2  ao_3  en_1  en_2  en_3  Final_1  Final_2  Final_3
0  100000003     1     1     1     1     1     1     1     1     1        1        1        1
1  100000009     1     0     1     4     4     4     4     4     4        1        0        1
2  100000009     4     0     1     1     1     4     1     1     4        1        0        1
3  100000009     1     0     1     1     0     0     1     0     0        1        0        0
或来自(c)@DSM和@piRSquared的该溶液:

In [194]: df.join(df.drop('KEY', 1)
                    .eq(1) 
                    .groupby(lambda c: c.rsplit('_', 1)[1], 1)
                    .all().astype(int).add_prefix('Final'))
Out[194]:
         KEY  RO_1  RO_2  RO_3  ao_1  ao_2  ao_3  en_1  en_2  en_3  Final1  Final2  Final3
0  100000003     1     1     1     1     1     1     1     1     1       1       1       1
1  100000009     1     0     1     4     4     4     4     4     4       0       0       0
2  100000009     4     0     1     1     1     4     1     1     4       0       0       0
3  100000009     1     0     1     1     0     0     1     0     0       1       0       0

如果您的结构是预定义的,则
numpy
提供了一个有效的解决方案:

n = 3
v = df.iloc[:,1:].values
v[v!=1] = 0

for i in range(1, n+1):
    df['Final'+str(i)] = (np.all(v[:, [i-1+n*k for k in range(n)]], axis=1)).astype(int)

#          KEY  RO_1  RO_2  RO_3  ao_1  ao_2  ao_3  en_1  en_2  en_3  Final1  \
# 0  100000003     1     1     1     1     1     1     1     1     1       1   
# 1  100000009     1     0     1     4     4     4     4     4     4       0   
# 2  100000009     4     0     1     1     1     4     1     1     4       0   
# 3  100000009     1     0     1     1     0     0     1     0     0       1   

#    Final2  Final3  
# 0       1       1  
# 1       0       0  
# 2       0       0  
# 3       0       0  

比较他想要的输出和他的代码,我认为OP更多的是在
(d==1).groupby(d.columns.str.split('''').str[-1],axis=1).all().astype(int)
(通常我避免使用正则表达式,因为我不喜欢它们。:-)还可以使用应用于索引的
lambda
df.join(df.drop('KEY',1.).groupby(lambda c:c.rsplit('u',1)[1],1]).all().astype(int).add_prefix('Final'))
更重要的一点是,我解释他的“如果''u 1'中的所有值都是'1',那么他将是1”,而
.isin([1])
的意思是
=1
。将他的期望值与您的值进行比较:他有一行0。@DSM您是否建议
df.join(df.drop('KEY',1.).eq(1).groupby(lambda c:c.rsplit('u',1)[1],1.).all().astype(int).添加_前缀('Final')
@DSM您正确解释了吗。我离开.isin()只是想看看多个条件的解决方案,但按照我提问的方式,您的回答是准确的。