Assigning values to Variables based on Conditions

Viewed 154

I want to find the mean of a column in a pandas dataframe if the value is numerical and find the mode of the series if the values are categorical. I only want to do this using one variable I call 'meanmode'.

When I try the following:

def mean_mode(val):
   return meanmode = val.mean() if val.dtype != 'object' else val.mode()[0]

I get the error:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

How can I assign the variable 'meanmode' its respective values of mean if numerical and mode if categorical?

My Code so far:

def report(val):
    dtypes = val.dtypes
    rows = val.T.apply(lambda x: x.count(), axis=1)
    nuniq = val.T.apply(lambda x: x.nunique() , axis=1)
    uniq = val.T.apply(lambda x: x.unique() if x.dtype == 'object' else None, axis=1)
    total = val.T.apply(lambda x: x.isna().sum(), axis=1)
    count = val.shape[0]
    pc = np.round(total / count * 100, 2)

    mini = val.min()
    maxi = val.max()

    meanmode = val.apply(lambda x: x.mode()[0] if x.dtype == 'object' else mean(val))

    qualitydf = pd.concat([dtypes, rows, total, pc, meanmode, mini, maxi, nuniq, uniq],
                          keys=['Dtype', 'Available Rows', 'Missing Values',
                                'Percent Missing', 'Mean-Mode',
                                'Min', 'Max', 
                                'No. Of Uniques', 'Unique Values'], axis=1)

return qualitydf
1 Answers

Use DataFrame.pipe:

df = pd.DataFrame({
        'A':list('abccef'),
         'B':[4,5,4,5,5,4],
         'C':[7,8,9,4,2,3],
         'D':[1,3,5,7,1,0],
         'E':[5,3,6,9,2,4],
         'F':list('baabbb')
})

def report(val):
    dtypes = val.dtypes
    rows = val.T.apply(lambda x: x.count(), axis=1)
    nuniq = val.T.apply(lambda x: x.nunique() , axis=1)
    uniq = val.T.apply(lambda x: x.unique() if x.dtype == 'object' else None, axis=1)
    total = val.T.apply(lambda x: x.isna().sum(), axis=1)
    count = val.shape[0]
    pc = np.round(total / count * 100, 2)

    mini = val.min()
    maxi = val.max()

    meanmode = val.apply(lambda x: x.mode()[0] if x.dtype == 'object' else mean(val))

    qualitydf = pd.concat([dtypes, rows, total, pc, meanmode, mini, maxi, nuniq, uniq],
                          keys=['Dtype', 'Available Rows', 'Missing Values',
                                'Percent Missing', 'Mean-Mode',
                                'Min', 'Max', 
                                'No. Of Uniques', 'Unique Values'], axis=1)

    return qualitydf

df = df.pipe(report)
print(df)
    Dtype  Available Rows  Missing Values  Percent Missing Mean-Mode Min Max  \
A  object               6               0              0.0         c   a   f   
B   int64               6               0              0.0         4   4   5   
C   int64               6               0              0.0         2   2   9   
D   int64               6               0              0.0         1   0   7   
E   int64               6               0              0.0         2   2   9   
F  object               6               0              0.0         b   a   b   

   No. Of Uniques       Unique Values  
A               5     [a, b, c, e, f]  
B               2              [4, 5]  
C               6  [7, 8, 9, 4, 2, 3]  
D               5     [1, 3, 5, 7, 0]  
E               6  [5, 3, 6, 9, 2, 4]  
F               2              [b, a]  
Related