Я хотел бы проверить, какие углы в массиве numpy находятся в пределах заданной альфа +/- дельты. Некоторые проблемы возникают, когда диапазон пересекает 0 или 360.
Если я проигнорирую граничные случаи, я мог бы сделать:
import numpy as np
def angleInRange(X,alpha,delta):
return (alpha - delta <= X) & (X <= alpha + delta)
Если я протестирую его с X = np.array([0, 5, 180, 355, 360])
, я получу
>>> print(angleInRange(X,170,30))
[False False True False False] # Correct
>>> print(angleInRange(X,10 ,30))
[ True True False False False] # 355 and 360 are not selected
>>> print(angleInRange(X,350,30))
[False False False True True] # 0 and 5 are not selected
Если я хочу получить правильный результат, мне нужно сделать что-то вроде
def angleInRange(X,alpha,delta):
test = ( ((alpha - delta <= X) & (X <= alpha + delta))
| ((alpha + 360 - delta <= X) & (X <= 360 ))
| (( 0 <= X) & (X <= alpha - 360 + delta))
)
return test
который уступает:
>>> print(angleInRange(X,170,30))
[False False True False False]
>>> print(angleInRange(X,10 ,30))
[ True True False True True ]
>>> print(angleInRange(X,350,30))
[True True False True True]
Это правильно, но есть ли более питонический и менее громоздкий способ добиться этого? Может ли здесь помочь оператор по модулю (%)?
Возможный дубликат Вычисление угла между двумя углами
Что касается |
и &
вместо or
и and
: факт в том, что X может быть либо массивом numpy, либо серией pandas. Хотя первые работают для обоих, or
и and
(а также цепное сравнение) не работают с пандами.
В вашем случае логично использовать цепные сравнения (a < X and X < b
становится a < X < b
) и логические операторы, которые замыкают (|
и &
проверяют как левый, так и правый операнды, даже если окончательный результат известен только с левым операндом, вместо этого используйте or
и and
):
test = ((alpha - delta <= X <= alpha + delta)
or (alpha + 360 - delta <= X <= 360 )
or ( 0 <= X <= alpha - 360 + delta))
Вероятно, вам помогут Эта почта или этот другой.
В основном таким образом вы используете свойство цикличности по модулю и углов:
def angleInRange(X, alpha, delta):
anglediff = (X - alpha + 180 + 360) % 360 - 180
return (-delta <= anglediff <= delta)
Хорошо, я сделаю это в следующий раз, но мне это кажется чем-то вроде изобретения велосипеда :)
не используйте
&
используйтеand