从可能的numpy数组中形成numpy数组

xnifntxz  于 2023-11-18  发布在  其他
关注(0)|答案(6)|浏览(129)

编辑

我意识到我没有很好地检查我的mwe,因此问了一些错误的问题。主要问题是当numpy数组作为2d数组而不是1d传入时(甚至当python列表作为1d而不是2d传入时)。因此,如果我们有

x = np.array([[1], [2], [3]])

字符串
那么很明显,如果你试图索引它,那么你将得到数组(如果你使用item,你不)。同样的事情也适用于标准的python列表。
抱歉,让你误会了。

原创

我试图从一个numpy数组或者一个标准的python列表中构造一个新的numpy数组。
例如

import numpy as np

x = [2, 3, 1]

y = np.array([[0, -x[2], x[1]], [x[2], 0, -x[0]], [-x[1], x[0], 0]])


现在我想构造一个函数,这样我就可以很容易地生成y

def skew(vector):
    """
    this function returns a numpy array with the skew symmetric cross product matrix for vector.
    the skew symmetric cross product matrix is defined such that
    np.cross(a, b) = np.dot(skew(a), b)

    :param vector: An array like vector to create the skew symmetric cross product matrix for
    :return: A numpy array of the skew symmetric cross product vector
    """

    return np.array([[0, -vector[2], vector[1]], 
                     [vector[2], 0, -vector[0]], 
                     [-vector[1], vector[0], 0]])


这工作得很好,我现在可以写(假设上面的功能包括在内)

import numpy as np

x=[2, 3, 1]

y = skew(x)


但是,我也希望能够在现有的1d或2d numpy数组上调用skew。

import numpy as np

x = np.array([2, 3, 1])

y = skew(x)


不幸的是,这样做会返回一个numpy数组,其中的元素也是numpy数组,而不是我希望的python浮点数。
有没有一种简单的方法来形成一个新的numpy数组,就像我从python列表或numpy数组中所做的那样,并且结果只是一个标准的numpy数组,每个元素都有浮点数?
显然,一个解决方案是检查输入是否是numpy数组:

def skew(vector):
    """
    this function returns a numpy array with the skew symmetric cross product matrix for vector.
    the skew symmetric cross product matrix is defined such that
    np.cross(a, b) = np.dot(skew(a), b)

    :param vector: An array like vector to create the skew symmetric cross product matrix for
    :return: A numpy array of the skew symmetric cross product vector
    """
    if isinstance(vector, np.ndarray):
        return np.array([[0, -vector.item(2), vector.item(1)],
                         [vector.item(2), 0, -vector.item(0)],
                         [-vector.item(1), vector.item(0), 0]])
    else:
        return np.array([[0, -vector[2], vector[1]], 
                         [vector[2], 0, -vector[0]], 
                         [-vector[1], vector[0], 0]])


但是,到处编写这些示例检查会变得非常乏味。
另一种解决方案是首先将所有内容强制转换为数组,然后仅使用数组调用

def skew(vector):
    """
    this function returns a numpy array with the skew symmetric cross product matrix for vector.
    the skew symmetric cross product matrix is defined such that
    np.cross(a, b) = np.dot(skew(a), b)

    :param vector: An array like vector to create the skew symmetric cross product matrix for
    :return: A numpy array of the skew symmetric cross product vector
    """

    vector = np.array(vector)

    return np.array([[0, -vector.item(2), vector.item(1)],
                     [vector.item(2), 0, -vector.item(0)],
                     [-vector.item(1), vector.item(0), 0]])


但我觉得这是低效的,因为它需要创建一个新的vector副本(在这种情况下,这不是什么大问题,因为vector很小,但这只是一个简单的例子)。
我的问题是,除了我所讨论的方法之外,还有其他方法吗?或者我坚持使用这些方法之一?

j2datikz

j2datikz1#

数组是可迭代的。你可以在skew函数中写:

def skew(x):
    return np.array([[0, -x[2], x[1]],
                     [x[2], 0, -x[0]],
                     [-x[1], x[0], 0]])
x = [1,2,3]
y = np.array([1,2,3])
>>> skew(y)
array([[ 0, -3,  2],
       [ 3,  0, -1],
       [-2,  1,  0]])
>>> skew(x)
array([[ 0, -3,  2],
       [ 3,  0, -1],
       [-2,  1,  0]])

字符串
在任何情况下,你的方法都以第一维元素结束,这些元素是包含浮点数的numpy数组。在任何情况下,你都需要调用第二维元素来获取里面的浮点数。
关于你在评论中告诉我的,你可以为2d数组添加一个if条件:

def skew(x):
     if (isinstance(x,ndarray) and len(x.shape)>=2):
         return np.array([[0, -x[2][0], x[1][0]],
                          [x[2][0], 0, -x[0][0]],
                          [-x[1][0], x[0][0], 0]])
     else:
         return np.array([[0, -x[2], x[1]],
                          [x[2], 0, -x[0]],
                          [-x[1], x[0], 0]])

nkhmeac6

nkhmeac62#

您可以使用numpy.asarray()有效地实现最后一个想法:

vector = np.asarray(vector)

字符串
然后,如果vector已经是NumPy数组,则不会发生复制。

wfypjpf4

wfypjpf43#

您可以保留函数的第一个版本,并将numpy数组转换为list

def skew(vector):

    if isinstance(vector, np.ndarray):
        vector = vector.tolist()

    return np.array([[0, -vector[2], vector[1]], 
                     [vector[2], 0, -vector[0]], 
                     [-vector[1], vector[0], 0]])

In [58]: skew([2, 3, 1])
Out[58]:
array([[ 0, -1,  3],
       [ 1,  0, -2],
       [-3,  2,  0]])

In [59]: skew(np.array([2, 3, 1]))
Out[59]:
array([[ 0, -1,  3],
       [ 1,  0, -2],
       [-3,  2,  0]])

字符串

7y4bm7vi

7y4bm7vi4#

这不是一个最佳的解决方案,但却是一个非常简单的解决方案。你可以在默认情况下将向量转换为列表。

def skew(vector): 
    vector = list(vector)
    return np.array([[0, -vector[2], vector[1]], 
                     [vector[2], 0, -vector[0]], 
                     [-vector[1], vector[0], 0]])

字符串

vatpfxk5

vatpfxk55#

在更少的行中

def skew(vector):
    return np.cross(np.eye(vector.size), vector.reshape(-1))

字符串

bmp9r5qi

bmp9r5qi6#

在这个老问题中添加另一个删除条件的选项。这个选项使用ravel(不复制)来“扁平化”数组,使其只有1D。

def skew(vector):
    """
    this function returns a numpy array with the skew symmetric cross product matrix for vector.
    the skew symmetric cross product matrix is defined such that
    np.cross(a, b) = np.dot(skew(a), b)

    :param vector: An array like vector to create the skew symmetric cross product matrix for
    :return: A numpy array of the skew symmetric cross product vector
    """

    vector = np.asarray(vector).ravel()

    return np.array([[0, -vector[2], vector[1]],
                     [vector[2], 0, -vector[0]],
                     [-vector[1], vector[0], 0]])

字符串
此外,对于那些感兴趣的人,在https://github.com/nasa/giant/blob/main/giant/rotations.py#L1164上有一个表单可以一次处理多个向量(使用多维数组

相关问题