【问题标题】:How to determine quadrant given x- and y-coordinate columns in Pandas DataFrame如何在 Pandas DataFrame 中确定给定 x 和 y 坐标列的象限
【发布时间】:2021-09-30 20:31:58
【问题描述】:

数据帧格式:

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

问题:如何编写循环来提供以下结果? 在每一卷中:

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  

【问题讨论】:

  • 注意:您的象限条件不完全包含笛卡尔平面:x == 0y &lt; 0 的点未被此逻辑捕获。您应该将 q4 的逻辑更改为 x &gt;= 0

标签: python pandas for-loop where-clause


【解决方案1】:

解决方案

这是另一个解决方案,使用arctan2 和一些模运算。请注意,Corralien 的方法更具通用性。下面的内容非常适用于这个用例。

import numpy as np

deg = np.round(180 * np.arctan2(df.y_center, df.x_center) / np.pi).astype(int)
df["quadrant"] = 1 + ((deg + 360) % 360) // 90

输出:

>>> 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

注意,轴上的点以逆时针方向“滚动”到相邻象限,例如,位于 90° 的点 (0, 0.631) 被视为象限 2;位于 180° 的(-0.578, 0) 被视为第 3 象限,以此类推。

步骤

使用np.arctan2() 得到每个(x, y) 点形成的角度(以度为单位):

>>> deg = np.round(180 * np.arctan2(df.y_center, df.x_center) / np.pi).astype(int)
>>> deg
0     15
1   -165
2   -157
3   -160
4     28
dtype: int32

现在,将(-180°, 180°] 转换为[0°, 360°)

>>> deg = (deg + 360) % 360
>>> deg
0     15
1    195
2    203
3    200
4     28
dtype: int32

将楼数除以 90 得到象限(将返回 0、1、2、3 - 所以还要加 1):

>>> quadrant = 1 + (deg // 90)
>>> quadrant
0    1
1    3
2    3
3    3
4    1
dtype: int32

【讨论】:

  • 我建议利用 np 设计 来处理数组这一事实。并避免apply 和额外的重新计算angles = np.round((180 / np.pi) * np.arctan2(df['y_center'], df['x_center']))
  • 哎呀。尴尬的疏忽。已修复,谢谢。
  • 也许如果你将角度从 0 转换为 360(而不是 -180 到 180),你可以取 90 的模数来获得右象限,不是吗?
  • 只是一个提示,创建一个包含整个代码的部分,以便 OP 像 TL;DR 一样使用
  • 已经这样做了,也许您需要刷新页面?
【解决方案2】:

使用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])

输出:

>>> 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

【讨论】:

  • 请注意:此逻辑并未完全捕获平面中的所有点。应在此处对位于轴上的点做出决定。否则,很好的答案。
  • @ddjohn。我根据您的评论更新了我的答案。如果你想检查。
  • 非常感谢,Corralien !真的很有帮助!
  • 如果这适合您的需要,请考虑answer an answer :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多