Home > Net >  How to determine quadrant given x- and y-coordinate columns in Pandas DataFrame
How to determine quadrant given x- and y-coordinate columns in Pandas DataFrame

Time:10-01

Dataframe format:

tooth_id x_center y_center width height quadrant
1 0.309643 0.082520 0.072325 0.169476
2 -0.211200 -0.057675 0.071321 0.199645
3 -0.307634 -0.127773 0.081366 0.187223
4 -0.262933 -0.093611 0.065294 0.211180
5 0.253139 0.136646 0.096936 0.190772

Question: how to write a loop to deliver the following outcome? In each roll:

if x_center >=0 and y_center >= 0, quadrant = 1
if x_center <0 and y_center >= 0,  quadrant = 2 
if x_center <0 and y_center <0,    quadrant = 3
if x_center >0 and y_center <0,    quadrant = 4  

CodePudding user response:

Use np.select:

# Update: change 'df.x_center > 0' to 'df.x_center >= 0'
# See comment of @ddejohn below

df['quadrant'] = np.select([(df.x_center >= 0) & (df.y_center >= 0),
                            (df.x_center < 0) & (df.y_center >= 0),
                            (df.x_center < 0) & (df.y_center < 0),
                            (df.x_center >= 0) & (df.y_center < 0)],
                           choicelist=[1, 2, 3, 4])

Output:

>>> df
   tooth_id  x_center  y_center     width    height  quadrant
0         1  0.309643  0.082520  0.072325  0.169476         1
1         2 -0.211200 -0.057675  0.071321  0.199645         3
2         3 -0.307634 -0.127773  0.081366  0.187223         3
3         4 -0.262933 -0.093611  0.065294  0.211180         3
4         5  0.253139  0.136646  0.096936  0.190772         1

CodePudding user response:

Okay, here's one possible solution. Corralien's answer is quite a bit more elegant for this particular task. Although at some point you may also be interested in the actual angle formed by the coordinates, so I'll leave this up:

>>> df
   tooth_id  x_center  y_center     width    height
0         1  0.309643  0.082520  0.072325  0.169476
1         2 -0.211200 -0.057675  0.071321  0.199645
2         3 -0.307634 -0.127773  0.081366  0.187223
3         4 -0.262933 -0.093611  0.065294  0.211180
4         5  0.253139  0.136646  0.096936  0.190772

>>> angles = df[["x_center", "y_center"]].apply(lambda r: round((180 / np.pi) * np.arctan2(r[1], r[0])), axis=1)
>>> angles
0     15
1   -165
2   -157
3   -160
4     28
dtype: int64

From here, we can define our four quadrants as a list of range objects:

q1 = range(0, 91)  # [0, 90] deg
q2 = range(90, 180)  # (90, 180]
q3 = range(-180, -90)  # [-180, -90)
q4 = range(-90, 0)  # (-90, 0)

Now we can use a nested where:

# quadrants =
np.where(angles.isin(q1), 1,
         np.where(angles.isin(q2), 2,
                  np.where(angles.isin(q3), 3,
                           np.where(angles.isin(q4), 4, np.nan))))

Output:

array([1, 3, 3, 3, 1])

Now assign that to df["quadrant"]:

>>> df["quadrant"] = quadrants
>>> df
   tooth_id  x_center  y_center     width    height  quadrant
0         1  0.309643  0.082520  0.072325  0.169476          1
1         2 -0.211200 -0.057675  0.071321  0.199645          3
2         3 -0.307634 -0.127773  0.081366  0.187223          3
3         4 -0.262933 -0.093611  0.065294  0.211180          3
4         5  0.253139  0.136646  0.096936  0.190772          1
  • Related