避免使用numpy数组嵌套if语句

时间:2019-07-10 15:14:51

标签: python python-3.x if-statement coordinates coordinate-transformation

我正在尝试转换坐标系,然后评估在GUI中定义了哪些坐标。稍后将为此功能构建此功能。目前,我正在尝试避免嵌套if语句。

本质上,想评估np.array是否为空。然后使用这些点评估变量,以检查它们是否为空。如果它们为空,则评估其中的语句。我试图避免更多的嵌套if语句,以及尽可能避免变量之间不必要的共享数据量。有什么建议吗?

我尝试构建多个变量,然后进行比较。尽管这也不一定是我想要的。

#!/bin/python3
import numpy as np
import math as m
import os
import sys
import ctypes

def cart2sp(x, y, z):
    """Converts data from cartesian coordinates into spherical.

    Args:
        x (scalar or array_like): X-component of data.
        y (scalar or array_like): Y-component of data.
        z (scalar or array_like): Z-component of data.

    Returns:
        Tuple (r, theta, phi) of data in spherical coordinates.
    """
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    scalar_input = False
    if x.ndim == 0 and y.ndim == 0 and z.ndim == 0:
        x = x[None]
        y = y[None]
        z = z[None]
        scalar_input = True
    r = np.sqrt(x**2+y**2+z**2)
    theta = np.arcsin(z/r)
    phi = np.arctan2(y, x)
    if scalar_input:
        return (r.squeeze(), theta.squeeze(), phi.squeeze())
    return (r, theta, phi)

def sp2cart(r, theta, phi):
    """Converts data in spherical coordinates into cartesian.

    Args:
        r (scalar or array_like): R-component of data.
        theta (scalar or array_like): Theta-component of data.
        phi (scalar or array_like): Phi-component of data.

    Returns:
        Tuple (x, y, z) of data in cartesian coordinates.
    """
    r = np.asarray(r)
    theta = np.asarray(theta)
    phi = np.asarray(phi)
    scalar_input = False
    if r.ndim == 0 and theta.ndim == 0 and phi.ndim == 0:
        r = r[None]
        theta = theta[None]
        phi = phi[None]
        scalar_input = True
    x = r*np.cos(theta)*np.cos(phi)
    y = r*np.cos(theta)*np.sin(phi)
    z = r*np.sin(theta)
    if scalar_input:
        return (x.squeeze(), y.squeeze(), z.squeeze())
    return (x, y, z)

def cart2cyl(x, y, z):
    """Converts data in cartesian coordinates into cylyndrical.

    Args:
        x (scalar or array_like): X-component of data.
        y (scalar or array_like): Y-component of data.
        z (scalar or array_like): Z-component of data.

    Returns:
        Tuple (r, phi, z) of data in cylindrical coordinates.
    """
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    scalar_input = False
    if x.ndim == 0 and y.ndim == 0 and z.ndim == 0:
        x = x[None]
        y = y[None]
        z = z[None]
        scalar_input = True
    r = np.sqrt(x**2+y**2)
    phi = np.arctan2(y, x)
    if scalar_input:
        return (r.squeeze(), phi.squeeze(), z.squeeze())
    return (r, phi, z)

def cyl2cart(r, phi, z):
    """Converts data in cylindrical coordinates into cartesian.

    Args:
        r (scalar or array_like): R-component of data.
        phi (scalar or array_like): Phi-component of data.
        z (scalar or array_like): Z-component of data.

    Returns:
        Tuple (x, y, z) of data in cartesian coordinates.
    """
    r = np.asarray(r)
    phi = np.asarray(phi)
    z = np.asarray(z)
    scalar_input = False
    if r.ndim == 0 and phi.ndim == 0 and z.ndim == 0:
        r = r[None]
        phi = phi[None]
        z = z[None]
        scalar_input = True
    x = r*np.cos(phi)
    y = r*np.sin(phi)
    if scalar_input:
        return (x.squeeze(), y.squeeze(), z.squeeze())
    return (x, y, z)

def mx_rot_x(gamma):
    """Returns rotational matrix for right-handed rotation
    around X axis.

    Args:
        gamma (scalar): Rotation angle around X in radians.

    Returns:
        Numpy rotational matrix.
    """
    return np.matrix([
        [1, 0, 0],
        [0, np.cos(gamma), -np.sin(gamma)],
        [0, np.sin(gamma), np.cos(gamma)]
    ])

def mx_rot_y(theta):
    """Returns rotational matrix for right-handed rotation
    around Y axis.

    Args:
        theta (scalar): Rotation angle around Y in radians.

    Returns:
        Numpy rotational matrix.
    """
    return np.matrix([
        [np.cos(theta), 0, np.sin(theta)],
        [0, 1, 0],
        [-np.sin(theta), 0, np.cos(theta)]
    ])

def mx_rot_z(phi):
    """Returns rotational matrix for right-handed rotation
    around Z axis.

    Args:
        phi (scalar): Rotation angle around Z in radians.

    Returns:
        Numpy rotational matrix.
    """
    return np.matrix([
        [np.cos(phi), -np.sin(phi), 0],
        [np.sin(phi), np.cos(phi), 0],
        [0, 0, 1]
    ])

def mx_rot(theta, phi, gamma):
    """Returns rotational matrix for compound rotation
    around X, Y and Z axes. The order of rotation is X-Y-Z.

    Args:
        theta (scalar): Rotation angle around Y in radians.
        phi (scalar): Rotational angle around in Z radians.
        gamma (scalar): Rotational angle around X in radians.

    Returns:
        Numpy rotational matrix.
    """
    return np.dot(
        mx_rot_z(phi),
        np.dot(mx_rot_y(theta), mx_rot_x(gamma))
    )

def mx_rot_reverse(theta, phi, gamma):
    """Returns rotational matrix for compound rotations
    around X, Y and Z axes. The order of rotation is Z-Y-X.

    Args:
        theta (scalar): Rotational angle around Y in radians.
        phi (scalar): Rotational angle around in Z radians.
        gamma (scalar): Rotational angle around X in radians.

    Returns:
        Numpy rotational matrix.
    """
    return np.dot(
        mx_rot_x(gamma),
        np.dot(mx_rot_y(theta), mx_rot_z(phi))
    )

def mx_apply(T, x, y, z):
    """Applies rotation to data using rotational matrix.

    Args:
        T (numpy.matrix): Rotational matrix.
        x (scalar or array_like): X-component of data.
        y (scalar or array_like): Y-component of data.
        z (scalar or array_like): Z-component of data.

    Returns:
        Tuple (x, y, z) of data in cartesian coordinates.
    """
    x = np.asarray(x)
    y = np.asarray(y)
    z = np.asarray(z)
    scalar_input = False
    if x.ndim == 0 and y.ndim == 0 and z.ndim == 0:
        x = x[None]
        y = y[None]
        z = z[None]
        scalar_input = True
    x_ = T[0, 0]*x+T[0, 1]*y+T[0, 2]*z
    y_ = T[1, 0]*x+T[1, 1]*y+T[1, 2]*z
    z_ = T[2, 0]*x+T[2, 1]*y+T[2, 2]*z
    if scalar_input:
        return (x_.squeeze(), y_.squeeze(), z_.squeeze())
    return (x_, y_, z_)

def cxform(cs_from, cs_to, dt, x, y, z):
    """Performs conversion between various geocentric and heliocentric
    coordinate systems.

    Args:
        cs_from (str): Indentifier of the source coordinate system.
            Can be one of 'GEI', 'J2000', 'GEO', 'MAG', 'GSE', 'GSM',
            'SM', 'RTN', 'GSEQ', 'HEE', 'HAE', 'HEEQ'.
        cs_to: Identifier of target coordinate system. Can be one of
            'GEI', 'J2000', 'GEO', 'MAG', 'GSE', 'GSM', 'SM', 'RTN',
            'GSEQ', 'HEE', 'HAE', 'HEEQ'.
        dt (datetime or array_like of datetime): Datetime of the
            conversion.
        x (scalar or array_like): X-component of data.
        y (scalar or array_like): Y-component of data.
        z (scalar or array_like): Z-component of data.

    Returns:
        Tuple (x, y, z) of data in target coordinate system.
    """
    if sys.platform == 'wind32' or sys.platform == 'cygwin':
        libcxform_path = os.path.join(
            os.path.dirname(__file__), 'cxform-c.dll'
        )
    else:
        libcxform_path = os.path.join(
            os.path.dirname(__file__), 'cxform-c.so'
        )
    libcxform = ctypes.CDLL(libcxform_path)
    dt = np.asarray(dt)
    x_from = np.asarray(x)
    y_from = np.asarray(y)
    z_from = np.asarray(z)
    if not dt.shape == x_from.shape == y_from.shape == z_from.shape:
        raise ValueError(
            "x, y, z and dt should be scalars or vectors of the same size"
        )
    scalar_input = False
    if dt.ndim == 0:
        dt = dt[None]
        x_from = x_from[None]
        y_from = y_from[None]
        z_from = z_from[None]
        scalar_input = True
    x_to = np.empty(x_from.shape)
    y_to = np.empty(y_from.shape)
    z_to = np.empty(z_from.shape)
    for i in range(dt.size):
        es = libcxform.date2es(
            ctypes.c_int(dt.flat[i].year),
            ctypes.c_int(dt.flat[i].month),
            ctypes.c_int(dt.flat[i].day),
            ctypes.c_int(dt.flat[i].hour),
            ctypes.c_int(dt.flat[i].minute),
            ctypes.c_int(dt.flat[i].second)
        )
        v_in = np.array(
            [x_from.flat[i], y_from.flat[i], z_from.flat[i]],
            dtype=np.float_
        )
        v_out = np.empty(3, dtype=np.float_)
        libcxform.cxform(
            str.encode(cs_from),
            str.encode(cs_to),
            ctypes.c_double(es),
            v_in.ctypes.data_as(ctypes.POINTER(ctypes.c_double)),
            v_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
        )
        x_to.flat[i] = v_out[0]
        y_to.flat[i] = v_out[1]
        z_to.flat[i] = v_out[2]
    if scalar_input:
        return (x_to.squeeze(), y_to.squeeze(), z_to.squeeze())
    return (x_to, y_to, z_to)



# Functions
def cart_2_cyl(pts):
    #Conversion - Start Cartesian (Cartesian to Cylindrical)
    pts[1,0], pts[1,1], pts[1,2] = cart2cyl(pts[0,0],pts[0,1],pts[0,2])
    #Read
    pos_cartcyl_cart = pts[1,0], pts[1,1], pts[1,2]
    return(pos_cartcyl_cart)

def cart_2_sph(pts):

    #Conversion - Start Spherical(Cartesian to Spherical)
    pts[2,0], pts[2,1] , pts[2,2] = cart2sp(pts[0,0], pts[0,1], pts[0,2])
    #Read
    pos_cartsph_cart = pts[2,0], pts[2,1], pts[2,2]   
    return(pos_cartsph_cart)


def sph_2_cart(pts):
    #Conversion - Start Spherical(Spherical to Cartesian)
    pts[0,0], pts[0,1], pts[0,2] = sp2cart(pts[2,0], pts[2,1], pts[2,2])
    #Read
    pos_sp2cart_sph = pts[0,0], pts[0,1], pts[0,2]
    return(pos_sp2cart_sph)

def cyl_2_cart(pts):
    #Conversion - Start Cylindrical (Cylindrical to Cartesian)
    pts[0,0], pts[0,1], pts[0,2] = cyl2cart(pts[1,0], pts[1,1], pts[1,2])
    #Read
    pos_cylcart_cyl = pts[0,0], pts[0,1], pts[0,2]
    return(pos_cylcart_cyl)

ThreeThree = (3,3)

pts = np.empty(ThreeThree)
pts = np.empty(ThreeThree)
pts = np.empty(ThreeThree)

cart = np.empty((1,3))
cyl = np.empty((1,3))
sph = np.empty((1,3))

# pts[2,0], pts[2,1], pts[2,2] = 1, 1, 1
# cart =  np.array((pts[2,0], pts[2,1], pts[2,2]))

pts[1,0], pts[1,1], pts[1,2] = 1, 1, 1
cyl =  np.array((pts[1,0], pts[1,1], pts[1,2]))

# pts[2,0], pts[2,1], pts[2,2] = 1, 1, 1
# sph =  np.array((pts[2,0], pts[2,1], pts[2,2]))


## MAIN LOGIC ##

if not pts.size == 0:
    # Check Cartesian
    if cart.size == 0:  #If cart array is empty -> Return True
        print("\nCartesian:", cart)
        if not cyl.any():
            print("Cylindrical Coordinates are Empty")
        else:

            print("Cylindrical:", cart_2_cyl(pts))

        if not sph.any():
            print("Spherical Coordinates are Empty")
        else:
            print("Spherical:", cart_2_sph(pts),'\n') 

    if not cyl.size == 0:
        print("\nCylindrical:", cyl)
        # Check Spherical
        if not sph.any():  #If sph array is empty -> Return True
            print("Spherical Coordinates are Empty")
        else:   
            cyl_2_cart(pts)
            print("Spherical:", cart_2_sph(pts))
        if not cart.any():
            print("\nCartesian Coordinates are Empty")
        else:
            print("Cartesian:", cyl_2_cart(pts),'\n')

    if sph.size == 0:
        print("\n Spherical:", sph)
        # Check Spherical
        if not cyl.any():  #If sph array is empty -> Return True
            print("Cylindrical Coordinates are Empty")
        else:   
            sph_2_cart(pts)
            print("Cylindrical:", cart_2_cyl(pts))
        if not cart.any():
            print("\nCartesian Coordinates are Empty")
        else:
            print("Cartesian:", cyl_2_cart(pts),'\n')

else:   
    print('Unsuccessful')

在设置了变量的情况下,我只希望对if(cart,cyl,sph).size == 0进行评估。

任何建议,谢谢。

0 个答案:

没有答案