1

I am trying to add column according to the existing column in dataframe following this page.
Since there are many if case, I defined the if case as function (getDirection method) and tried to call by apply method(addDirection method).
Howerver, I got following error.

TypeError: getDirection() takes 1 positional argument but 2 were given  

Can anyone tell how I can call function by apply for dataframe?
Code is shown below.

def addDirection(self):
    group=self.group
    group['direction']=group['Azimuth [deg]'].apply(self.getDirection)

   def getDirection(angle):
        if angle < 11.25 or angle >= 348.75:
            return "N"
        elif angle < 33.75 and angle >= 11.25:
            return "NNE"
        elif angle < 56.25 and angle >= 33.75:
            return "NE"
        elif angle < 78.75 and angle >= 56.25:
            return "ENE"
        elif angle < 101.25 and angle >= 78.75:
            return "E"
        elif angle < 123.75 and angle >= 101.25:
            return "ESE"
        elif angle < 146.25 and angle >= 123.75:
            return "SE"
        elif angle < 168.75 and angle >= 146.25:
            return "SSE"
        elif angle < 191.25 and angle >= 168.75:
            return "S"
        elif angle < 213.75 and angle >= 191.25:
            return "SSW"
        elif angle < 236.25 and angle >= 213.75:
            return "SW"
        elif angle < 258.75 and angle >= 236.25:
            return "WSW"
        elif angle < 281.25 and angle >= 258.75:
            return "W"
        elif angle < 303.75 and angle >= 281.25:
            return "WNW"
        elif angle < 326.25 and angle >= 303.75:
            return "NW"
        elif angle < 348.75 and angle >= 326.25:
            return "NNW"
5
  • How did you apply the getDirection() method? Commented Dec 3, 2017 at 14:13
  • 1
    getDirection appears to be a method in some class, not a regular function. Commented Dec 3, 2017 at 14:20
  • @akilat90 Referring to this page, I suppose below script is applying the getDirection() method to dataframe. 'group['direction']=group['Azimuth [deg]'].apply(self.getDirection)' Commented Dec 3, 2017 at 14:20
  • This is a lot more concisely implemented as a list lookup: return ["N", "NNE", "NE, "ENE", ...][int((angle*100)//1125]. Commented Dec 3, 2017 at 14:27
  • How are you calling addDirection? Commented Dec 3, 2017 at 14:51

2 Answers 2

4

When calling self.getDirection(a), you are implicitly calling getDirection(self, a). This is why the error message states that two arguments were given instead of one (self and the element of the series).

The way you call the function (prepending self.) implies that it is not a static method, but rather an instance method. Instance methods are defined inside a class; their result typically depends on the internal state of the object (instance of the class) you are calling it on.

If you called the function as an instance method by mistake, you should write apply(getDirection) instead of apply(self.getDirection). Most likely this is what you want, since the function's outcome depends only on angle and not on any object's internal state.

If you want getDirection to be an instance method, define the function as def getDirection(self, a). You don't have to change anything else.

See also this answer on instance and class methods.

Sign up to request clarification or add additional context in comments.

Comments

2

As @Cornflex said is because you are passing additional paramter using self so you got that error. Either do def getDirection(self,angle) or just apply.(getDirection)

Since its pandas instead of that many if else's we can just do binning using pd.cut i.e

df = pd.DataFrame({'Azimuth [deg]':[300,340,150]})
bins = [11.25, 33.75, 56.25, 78.75, 101.25, 123.75, 146.25, 168.75, 191.25, 213.75, 236.25, 258.75, 281.75, 303.75, 326.25, 348.75]

labels = ['NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']

pd.cut(df['Azimuth [deg]'],bins=bins,labels=labels).fillna('N') # fillna is for your first condition.

0    WNW
1    NNW
2    SSE
Name: Azimuth [deg], dtype: category
Categories (15, object): [NNE < NE < ENE < E ... W < WNW < NW < NNW]
In [557]:

df['Azimuth [deg]'].apply(getDirection)

0    WNW
1    NNW
2    SSE
Name: Azimuth [deg], dtype: object 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.