5

My class takes a row of a dataframe to construct an object and I would like to create an array of objects by applying init to every row of a dataframe. Is there a way to vectorize this? My class definition looks like

class A(object):
    def __init__(self,row):
        self.a = row['a']
        self.b = row['b']

Any suggestion will be highly appreciated!

I have one way which I am not that satisfied with to solve this problem. Define another function outside of class and then use apply.

def InitA(row):
    return A(row)

Assume df is the data frame I want to use as argument.

xxx = df.apply(InitA,axis=1)

gives what I want. However, I don't think InitA is necessary.

My original problem is a bit more complicated. The class definition is

class A(object):
    def __init__(self):
        return
    def add_parameter(self,row):
        self.a = row['a']

I intend to apply add_parameter to every row of a data frame. But I think defining another (lambda) function is necessary to solve this problem.

Conan
  • 95
  • 1
  • 2
  • 7

2 Answers2

3

Just use a lambda function?

xxx = df.apply(lambda x: A(x),axis=1)

edit: Another solution is to directly pass the class, the apply-function then calls the constructor:

xxx = df.apply(A,axis=1)

this works:

import pandas as pd 

class C(object):
    def __init__(self,dat):
        return

A = pd.DataFrame({'a':pd.Series([1,2,3])})
A.apply(lambda x: C(x),axis=1)
McRip
  • 100
  • 1
  • 6
  • Using a lambda function is a concise way of defining InitA outside. I am hoping there is a way to totally avoid defining another function. But maybe this does not exist. – Conan Jan 06 '16 at 10:53
  • Yes, this is a good solution. My original problem problem is a bit more complicated than the one posted here. I now think a lambda function will be needed for solving it. Thank you for help! – Conan Jan 06 '16 at 11:11
  • It is not recommended within python to return from the `__init__`. – jason m Nov 08 '21 at 20:29
0

I think the best course of action IMO (I do feel this is subjective) would be to create a wrap function on your class.

I do not know if this is really the best solution but it is a better practice than the answer accepted.

def wrap_class(row_element):
    
    c = MyClass(arg=row_element)
    return c.DoStuff()

Returning from the __init__ is strongly discouraged.

jason m
  • 6,519
  • 20
  • 69
  • 122