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