pythonpandas

How to do a majority voting on columns in pandas


I have a dataframe which has 10 different columns, A1, A2, ...,A10. These columns contain y or n. I'd like to create another column whose value is y if the majority of columns (A1, A2, ...,A10) are y and n otherwise. How can I do this?


Solution

  • Use DataFrame.mode:

    df['majority'] = df.mode(axis=1)[0]
    

    Example

    np.random.seed(0)
    df = pd.DataFrame(np.random.choice(['y', 'n'], size=(10, 10)))
    print(df)
    
       0  1  2  3  4  5  6  7  8  9
    0  y  n  n  y  n  n  n  n  n  n
    1  n  y  y  n  y  y  y  y  y  n
    2  y  n  n  y  y  n  n  n  n  y
    3  n  y  n  y  n  n  y  n  n  y
    4  y  n  y  n  n  n  n  n  y  n
    5  y  n  n  n  n  y  n  y  y  n
    6  n  y  n  y  n  y  y  y  y  y
    7  n  n  y  y  y  n  n  y  n  y
    8  y  n  y  n  n  n  n  n  n  y
    9  n  n  y  y  n  y  y  n  n  y
    
    df['majority'] = df.mode(axis=1)[0]
    print(df)
    
       0  1  2  3  4  5  6  7  8  9 majority
    0  y  n  n  y  n  n  n  n  n  n        n
    1  n  y  y  n  y  y  y  y  y  n        y
    2  y  n  n  y  y  n  n  n  n  y        n
    3  n  y  n  y  n  n  y  n  n  y        n
    4  y  n  y  n  n  n  n  n  y  n        n
    5  y  n  n  n  n  y  n  y  y  n        n
    6  n  y  n  y  n  y  y  y  y  y        y
    7  n  n  y  y  y  n  n  y  n  y        n
    8  y  n  y  n  n  n  n  n  n  y        n
    9  n  n  y  y  n  y  y  n  n  y        n
    

    If it is necessary to handle the distinction between true majority and split decisions, you could use numpy.where. eg:

    mode = df.mode(axis=1)
    
    df['majority'] = np.where(mode.isna().any(axis=1), mode[0], 'split')
    print(df)
    
       0  1  2  3  4  5  6  7  8  9 majority
    0  y  n  n  y  n  n  n  n  n  n        n
    1  n  y  y  n  y  y  y  y  y  n        y
    2  y  n  n  y  y  n  n  n  n  y        n
    3  n  y  n  y  n  n  y  n  n  y        n
    4  y  n  y  n  n  n  n  n  y  n        n
    5  y  n  n  n  n  y  n  y  y  n        n
    6  n  y  n  y  n  y  y  y  y  y        y
    7  n  n  y  y  y  n  n  y  n  y    split
    8  y  n  y  n  n  n  n  n  n  y        n
    9  n  n  y  y  n  y  y  n  n  y    split