Python尝试不使用np.arccos

Python尝试不使用np.arccos,python,python-3.x,numpy,Python,Python 3.x,Numpy,这是我在这里的第一个问题,如果我做错了,请指出我 我用这个方程来计算一个球面角()。由于math.acos和np.arccos仅为[-1,1]定义,因此我需要编写try/except语句。它在math.acos上运行得很好,但我一直在学习 RuntimeWarning:在arccos中遇到无效值 当我使用np.arccos时。因为我想计算一个很长文件的球面角,所以我需要np.arccos,这样我就可以得到矢量化的好处。关于为什么会发生这种情况,或者我如何改进代码,有什么想法吗 以下是我的尝试:

这是我在这里的第一个问题,如果我做错了,请指出我

我用这个方程来计算一个球面角()。由于math.acos和np.arccos仅为[-1,1]定义,因此我需要编写try/except语句。它在math.acos上运行得很好,但我一直在学习

RuntimeWarning:在arccos中遇到无效值

当我使用np.arccos时。因为我想计算一个很长文件的球面角,所以我需要np.arccos,这样我就可以得到矢量化的好处。关于为什么会发生这种情况,或者我如何改进代码,有什么想法吗

以下是我的尝试:

import numpy as np
import math

def spherical_to_cartesian(latr, lonr):
    """Convert a point given latitude and longitude in radians to
    3D cartesian coordinates, assuming a sphere radius of one."""
    return np.array((
        np.cos(latr) * np.cos(lonr),
        np.cos(latr) * np.sin(lonr),
        np.sin(latr)
    ))

def angle_between_vectors(u, v):
    'Return the angle between two vectors in any dimension space in radians'
    return np.arccos(np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v)))

def angle_3pts(p1, p2, p3):
    'Convert the points to numpy latitude/longitude radians space'
    p1_rad = np.radians(np.array(p1))
    p2_rad = np.radians(np.array(p2))
    p3_rad = np.radians(np.array(p3))

    'The points in 3D cartesian coordinates'
    p1_cartesian = spherical_to_cartesian(*p1_rad)
    p2_cartesian = spherical_to_cartesian(*p2_rad)
    p3_cartesian = spherical_to_cartesian(*p3_rad)

    'The angle between vectors'
    ang_12 = angle_between_vectors(p1_cartesian, p2_cartesian)
    ang_23 = angle_between_vectors(p2_cartesian, p3_cartesian)
    ang_31 = angle_between_vectors(p3_cartesian, p1_cartesian)
    print(ang_12, ang_23, ang_31)

    '''Calculate spherical angle: 
       https://en.wikipedia.org/wiki/Solution_of_triangles#Solving_spherical_triangles'''
    print((np.cos(ang_31) - np.cos(ang_12)*np.cos(ang_23))/(np.sin(ang_12)*np.sin(ang_23)))

    try:
        angle_3d = np.degrees(np.arccos((np.cos(ang_31) - np.cos(ang_12)*np.cos(ang_23))/(np.sin(ang_12)*np.sin(ang_23))))
    except:
        angle_3d = 180.

    return angle_3d


point1 = (0, 0)
point2 = (0, 10)
point3 = (0, 20)

ang = angle_3pts(point1, point2, point3)

当我在try公式中使用math.acos时,它工作得很好,但是np.arccos会产生错误

arccos
是一个
ufunc
,并在其中取
参数:

In [226]: x = np.linspace(-2,2,20)
In [227]: np.arccos(x, where=(abs(x)<1), out=np.full_like(x,np.pi))
Out[227]: 
array([3.14159265, 3.14159265, 3.14159265, 3.14159265, 3.14159265,
       2.8157097 , 2.39918372, 2.12505816, 1.89208492, 1.67625485,
       1.4653378 , 1.24950774, 1.01653449, 0.74240893, 0.32588296,
       3.14159265, 3.14159265, 3.14159265, 3.14159265, 3.14159265])

这并不是一个例外。看一看,就是这样!非常感谢,@DanMašek感谢您的解释!使用where/out完全符合我的代码
def foo(x):
    try:
        return math.acos(x)
    except ValueError:
        return math.pi
In [239]: np.array([foo(i) for i in x])
Out[239]: 
array([3.14159265, 3.14159265, 3.14159265, 3.14159265, 3.14159265,
       2.8157097 , 2.39918372, 2.12505816, 1.89208492, 1.67625485,
       1.4653378 , 1.24950774, 1.01653449, 0.74240893, 0.32588296,
       3.14159265, 3.14159265, 3.14159265, 3.14159265, 3.14159265])