将多个列合并为一个列pandas

时间:2018-02-17 15:34:07

标签: python pandas pandas-groupby

我有一个df,它有多个以相同值结尾的列。我想将列合并到一个最后一列。例如,任何以' _1'应该进入标有' final_1'的新列。如果' _1'中的所有值,则final_1中的值将为1。是' 1'否则例如,如果至少有一个值不是&#39在' _1'列。

如果我的解释不是,原始和最终结果数据帧会更清晰。

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)

2 个答案:

答案 0 :(得分:2)

@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

答案 1 :(得分: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