我有一些代码可以将角度与它们所属的圆圈的象限相匹配。它目前给了我想要的结果,但是我试图失去for循环以充分利用numpy的速度。
import numpy as np
angle = np.array([350, 10, 80, 100, 170, 190, 260, 280])
# Center of each quadrant
spawn_angles = np.array([0, 90, 180, 270])
segment_degrees = np.diff(spawn_angles)[0]
lower_bounds = spawn_angles - (segment_degrees / 2)
upper_bounds = spawn_angles + (segment_degrees / 2)
max_upper = upper_bounds.max()
# Wrap angles larger than the upper bound of the last segment
# back to a negative angle
angle[angle > max_upper] -= 360
quadrant = np.zeros_like(angle, dtype=np.float64)
# Want to make sure that quadrants that don't get calculated
# properly get assigned an invalid number, i.e. -1
quadrant.fill(-1)
for segment_num in range(len(spawn_angles)):
in_segment = ((angle > lower_bounds[segment_num]) &
(angle < upper_bounds[segment_num]))
quadrant[in_segment] = segment_num
# Expected/current output
quadrant
Out[16]: array([ 0., 0., 1., 1., 2., 2., 3., 3.])
基本上,我无法弄清楚如何在numpy中做的部分是>
/ <
比较。
如果角度介于lower_bounds[0]
和upper_bounds[0]
之间,则为相应的条目
quadrant
的{0}被赋予0,类似于象限1,2,3,有没有办法
将角度数组同时与lower_bound
和/或upper_bound
的所有条目进行比较?
(如果此代码看起来过于复杂,其中一些是因为spawn_angles
/象限中心
不总是[0, 90, 180, 270]
,它们也可以是例如[45, 135, 225, 315]
)
答案 0 :(得分:1)
您需要将所有内容提升到一个维度。您需要一个2D数组,每个角度为一行,每个segment_num为一列。 (或许你想要转置,但如果是这样,你应该能够从这里想出来。)
如果您只是a > b
a
和b
都是1D数组,那么您需要进行1对1的元素比较。
但如果a
是2D数组,那么您需要进行笛卡尔积比较。
换句话说:
>>> array.reshape((8,1)) > lower_bounds
array([[ True, True, True, True],
[ True, False, False, False],
[ True, True, False, False],
[ True, True, False, False],
[ True, True, True, False],
[ True, True, True, False],
[ True, True, True, True],
[ True, True, True, True]], dtype=bool)
你应该能够从那里弄明白。
答案 1 :(得分:1)
感谢abarnert对这里的关键见解。我重写的矢量化代码:
import numpy as np
angle = np.array([350, 10, 80, 100, 170, 190, 260, 280])
# Center of each quadrant
spawn_angles = np.array([0, 90, 180, 270])
segment_degrees = np.diff(spawn_angles)[0]
lower_bounds = spawn_angles - (segment_degrees / 2)
upper_bounds = spawn_angles + (segment_degrees / 2)
max_upper = upper_bounds.max()
# Wrap angles larger than the upper bound of the last segment
# back to a negative angle
angle[angle > max_upper] -= 360
angle_2d = angle.reshape((len(angle), 1))
cmp_array = ((angle_2d > lower_bounds) &
(angle_2d < upper_bounds))
quadrant = np.argwhere(cmp_array)[:, 1]
quadrant
Out[29]: array([0, 0, 1, 1, 2, 2, 3, 3], dtype=int64)