Covert Function to Class

Viewed 52

This is my sample input and output:

df=pd.DataFrame({'A_flag': [1, 1,1], 'B_flag': [1, 1,0],'C_flag': [0, 1,0],'A_value': [5, 3,7], 'B_value': [2, 7,4],'C_value': [4, 2,5]})

df1=pd.DataFrame({'A_flag': [1, 1,1], 'B_flag': [1, 1,0],'C_flag': [0, 1,0],'A_value': [5, 3,7], 'B_value': [2, 7,4],'C_value': [4, 2,5], 'Value':[3.5,3,7], 'Name':['A_B','A_B_C','A']})

I want to generate another column called 'Value' conditional on A_flag, B_flag and C_flag, and return the mean of value if its corresponding flag is 1.'Name' just shows which flag is equal to 1.

Here are my functions and they work, I want to use class to achieve this purpose:

def A_value(row):
    
    
    flags = [(row['A_flag'], row['A_value']), (row['B_flag'], row['B_value']), (row['C_flag'], row['C_value'])]
    
    met_condition = [row[1] for row in flags if row[0] == 1]
    
    return sum(met_condition) / len(met_condition)



def A_name(row):

    row=row[["A_flag", "B_flag", "C_flag"]]
    
    met_condition = list(row[row.eq(1)].index)

    if len(met_condition)==3:
        return "A_B_C"
    elif len(met_condition)==2:
        return met_condition[0]+'_'+ met_condition[1]
    return met_condition[0]



def df_with_A_related_info(df):
    
    df['Total']=df.apply(lambda x: A_value(x),axis=1)
    df['Name']=df.apply(lambda x: A_name(x),axis=1)
    
    return df

Function 'A_name' and 'A_value' are row operations for my df and then function 'df_with_A_related_info' is just to add A related variables (name and value) to existing df.

I am new to class and OPP and trying to covert it into class. Not sure how to implement this function but in class.

class A:
    
    def __init__(self,df):
        self.df=df

    
    def value(self):
        
        flags = [(self.df['A_flag'], self.df['A_value']), 
                 (self.df['B_flag'], self.df['B_value']), 
                 (self.df['C_flag'], self.df['C_value'])]

        met_condition = [row[1] for row in flags if row[0] == 1]
    
        return sum(met_condition) / len(met_condition)



    def name(self):

        row=self.df[["A_flag", "B_flag", "C_flag"]]
    
        met_condition = list(row[row.eq(1)].index)

        if len(met_condition)==3:
            return "A_B_C"
        elif len(met_condition)==2:
            return met_condition[0]+'_'+ met_condition[1]
        return met_condition[0]

How do I use class and achieve the same purpose as my original functions? Originally, I generate name and value function for row operation and call them using lambda function to generate two variables I want for my df. I tried:

df['name']=df.apply(lambda row : A(row).name())
df['value']=df.apply(lambda row : A(row).value())

It just gave me the object.

1 Answers

Don't reassign self.df in the name method. In the original function, row is a local variable, so assigning it has no effect outside the function. But self.df is a permanent attribute of the A instance, so you're changing the object that will be used in future calls.

You can use the same local variable row as in the original function.

    def name(self):

        row=self.df[["A_flag", "B_flag", "C_flag"]]
    
        met_condition = list(row[row.eq(1)].index)

        if len(met_condition)==3:
            return "A_B_C"
        elif len(met_condition)==2:
            return met_condition[0]+'_'+ met_condition[1]
        return met_condition[0]
Related