How can I map the headers to columns in pandas?

前端 未结 5 1562
隐瞒了意图╮
隐瞒了意图╮ 2020-12-16 01:15

I have a dataframe like :

A    B    C 
1    0    0
1    1    0
0    1    0
0    0    1

I want to have :

 A    B    C  lab         


        
相关标签:
5条回答
  • 2020-12-16 01:47

    Using dot

    df.assign(label=df.dot(df.columns))
    
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    

    Same thing using underlying numpy arrays

    df.assign(label=df.values.dot(df.columns.values))
    
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    
    0 讨论(0)
  • 2020-12-16 01:48
    In [101]: df['label'] = df.apply(lambda x: ''.join(df.columns[x.astype(bool)].tolist()), axis=1)
    
    In [102]: df
    Out[102]:
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    

    PS i would definitely chose @Ted's solution as it's much nicer and much much much ... faster

    0 讨论(0)
  • 2020-12-16 01:51

    Or using melt and groupby

    df1 = df.reset_index().melt('index')
    df1 = df1[df1.value==1]
    df['label'] = df1.groupby('index').variable.sum()
    df
    
    Out[976]: 
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    

    Or

    df['label'] = df.T.apply(lambda x: ''.join(x.index[x==1]),axis=0)
    df
    Out[984]: 
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    
    0 讨论(0)
  • 2020-12-16 01:52
    df = df.assign(label=[''.join([df.columns[n] for n, bool in enumerate(row) if bool]) 
                          for _, row in df.iterrows()])
    >>> df
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    

    Timings

    # Set-up:
    df_ = pd.concat([df] * 10000)
    
    %%timeit
    # Solution by @Wen 
    df1 = df_.reset_index().melt('index')
    df1 = df1[df1.value==1]
    df['label'] = df1.groupby('index').variable.sum()
    # 10 loops, best of 3: 47.6 ms per loop
    
    %%timeit
    # Solution by @MaxU
    df_['label'] = df_.apply(lambda x: ''.join(df_.columns[x.astype(bool)].tolist()), axis=1)
    # 1 loop, best of 3: 4.99 s per loop
    
    %%timeit
    # Solution by @TedPetrou
    df_['label'] = np.where(df_, df_.columns, '').sum(axis=1)
    # 100 loops, best of 3: 12.5 ms per loop
    
    %%timeit
    # Solution by @Alexander
    df_['label'] = [''.join([df_.columns[n] for n, bool in enumerate(row) if bool]) for _, row in df_.iterrows()]
    # 1 loop, best of 3: 3.75 s per loop
    
    %%time
    # Solution by @PiRSquared
    df_['label'] = df_.dot(df_.columns)
    # CPU times: user 18.1 ms, sys: 706 µs, total: 18.8 ms
    # Wall time: 18.9 ms
    
    0 讨论(0)
  • 2020-12-16 02:07

    Here is an idiomatic and performant solution

    df['label'] = np.where(df, df.columns, '').sum(axis=1)
    
       A  B  C label
    0  1  0  0     A
    1  1  1  0    AB
    2  0  1  0     B
    3  0  0  1     C
    
    0 讨论(0)
提交回复
热议问题