将行中的最高值设置为1并在pandas中将其设置为0

时间:2018-05-25 20:59:08

标签: python pandas conditional-statements

我的原始数据框如下所示:

A       B       C
0.10    0.83    0.07
0.40    0.30    0.30
0.70    0.17    0.13    
0.72    0.04    0.24    
0.15    0.07    0.78    

我希望每行变为二值化:1将分配给具有最高值的列,其余的将设置为0,因此之前的数据帧将变为:

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

如何做到这一点?
感谢。

编辑:据我所知,一个具体案例使我的问题含糊不清。我应该说,如果给定行的3列相等,我仍然希望获得[1 0 0]向量而不是[1 1 1]该行。

3 个答案:

答案 0 :(得分:6)

numpy argmax

一起使用
m = np.zeros_like(df.values)
m[np.arange(len(df)), df.values.argmax(1)] = 1

df1 = pd.DataFrame(m, columns = df.columns).astype(int)

# Result


   A  B  C
0  0  1  0
1  1  0  0
2  1  0  0
3  1  0  0
4  0  0  1

<强> 计时

df_test = df.concat([df] * 1000)

def chris_z(df):
     m = np.zeros_like(df.values)
     m[np.arange(len(df)), df.values.argmax(1)] = 1
     return pd.DataFrame(m, columns = df.columns).astype(int)

def haleemur(df):
    return df.apply(lambda x: x == x.max(), axis=1).astype(int)

def haleemur_2(df):
    return pd.DataFrame((df.T == df.T.max()).T.astype(int), columns=df.columns)

def sacul(df):
    return pd.DataFrame(np.where(df.T == df.T.max(), 1, 0),index=df.columns).T

<强> 结果

In [320]: %timeit chris_z(df_test)
358 µs ± 1.08 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [321]: %timeit haleemur(df_test)
1.14 s ± 45.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [329]: %timeit haleemur_2(df_test)
972 µs ± 11.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [333]: %timeit sacul(df_test)
1.01 ms ± 3.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

答案 1 :(得分:2)

 df.apply(lambda x: x == x.max(), axis=1).astype(int) 

应该这样做。这可以通过检查值是否是该列的最大值,然后转换为整数(True - > 1,False - > 0)来实现

而不是apply - 逐行lambda,也可以转置数据帧&amp;与max比较,然后转置回来

(df.T == df.T.max()).T.astype(int)

最后,一个非常快速的基于numpy的解决方案:

pd.DataFrame((df.T.values == np.amax(df.values, 1)).T*1, columns = df.columns)

输出在所有情况下:

   A  B  C
0  0  1  0
1  1  0  0
2  1  0  0
3  1  0  0
4  0  0  1

答案 2 :(得分:2)

另一个numpy方法,使用np.where

import numpy as np
new_df = pd.DataFrame(np.where(df.T == df.T.max(), 1, 0),index=df.columns).T
   A  B  C
0  0  1  0
1  1  0  0
2  1  0  0
3  1  0  0
4  0  0  1