Ângelo
Ângelo

Reputation: 169

Using apply function Dataframe

I need help correcting an error I am getting.

I have the following dataframe:

x = [-0.75853, -0.75853, -0.75853, -0.75852]
y = [-0.63435, -0.63434, -0.63435, -0.63436]
z = [-0.10488, -0.10490, -0.10492, -0.10495]
w = [-0.10597, -0.10597, -0.10597, -0.10596]

df = pd.DataFrame([x, y, z, w], columns=['x', 'y', 'z', 'w'])

I created the following functions:

import math
def roll(qw, qx, qy, qz):
    # x-axis rotation
    sinr_cosp = +2.0 * (qw * qx + qy + qz)
    cosr_cosp = +1.0 - 2.0 * (qx * qx + qy * qy)
    roll = math.atan2(sinr_cosp, cosr_cosp)
    return roll

def pitch(qw, qx, qy, qz):
    # y-axis rotation
    sinp = +2.0 * (qw * qy - qz * qx)
    if(math.fabs(sinp) >= 1):
        pitch = copysign(M_PI/2, sinp)
    else:
        pitch = math.asin(sinp)
    return sinp

def yaw(qw, qx, qy, qz):
    # z-axis rotation
    siny_cosp = +2.0 * (qw * qz + qx * qy)
    cosy_cosp = +1.0 - 2.0 * (qy * qy + qz * qz)
    yaw = math.atan2(siny_cosp, cosy_cosp)
    return yaw

Finally, using Pandas apply function, I tried to associate the result with a new column:

q_w = df['w']
q_x = df['x']
q_y = df['y']
q_z = df['z']

df['row'] = df.apply(roll(q_w, q_x, q_y, q_z))

The same error occurs when using the other functions.

I saw an issue right here on Stack where this bug was fixed using Numpy. I believe this is not possible here because I am using functions specific to the Math package.

TypeError Traceback (most recent call last) /usr/local/lib/python3.6/dist-packages/pandas/core/series.py in wrapper(self) 92 raise TypeError("cannot convert the series to " ---> 93 "{0}".format(str(converter))) 94

TypeError: cannot convert the series to

The above exception was the direct cause of the following exception:

SystemError Traceback (most recent call last) 4 frames in () ----> 1 df['row'] = df.apply(roll(q_w, q_x, q_y, q_z))

in roll(qw, qx, qy, qz) 4 sinr_cosp = +2.0 * (qw * qx + qy + qz) 5 cosr_cosp = +1.0 - 2.0 * (qx * qx + qy * qy) ----> 6 roll = math.atan2(sinr_cosp, cosr_cosp) 7 return roll 8

/usr/local/lib/python3.6/dist-packages/pandas/core/series.py in wrapper(self) 88 89 def wrapper(self): ---> 90 if len(self) == 1: 91 return converter(self.iloc[0]) 92 raise TypeError("cannot convert the series to "

/usr/local/lib/python3.6/dist-packages/pandas/core/series.py in len(self) 593 Return the length of the Series. 594 """ --> 595 return len(self._data) 596 597 def view(self, dtype=None):

/usr/local/lib/python3.6/dist-packages/pandas/core/internals/managers.py in len(self) 290 291 def len(self): --> 292 return len(self.items) 293 294 def unicode(self):

SystemError: PyEval_EvalFrameEx returned a result with an error set

Upvotes: 0

Views: 265

Answers (2)

Michael Gardner
Michael Gardner

Reputation: 1813

You could also modify your function.

def roll(df):
    # x-axis rotation
    sinr_cosp = +2.0 * (df.w * df.x + df.y + df.z)
    cosr_cosp = +1.0 - 2.0 * (df.x * df.x + df.y * df.y)
    roll = math.atan2(sinr_cosp, cosr_cosp)
    return roll

df.apply(roll, axis=1)

Out:

0   -2.175472
1   -1.909103
2   -0.394163
3   -0.397885
dtype: float64

Upvotes: 1

BENY
BENY

Reputation: 323396

You should using apply like

df.apply(lambda x : roll(x['w'],x['x'],x['y'],x['z']),1)
Out[291]: 
0   -2.175472
1   -1.909103
2   -0.394163
3   -0.397885
dtype: float64

Upvotes: 4

Related Questions