简体   繁体   English

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

[英]form numpy array from possible numpy array

EDIT编辑

I realized that I did not check my mwe very well and as such asked something of the wrong question.我意识到我没有很好地检查我的 mwe,因此问了一些错误的问题。 The main problem is when the numpy array is passed in as a 2d array instead of 1d (or even when a python list is passed in as 1d instead of 2d).主要问题是当 numpy 数组作为 2d 数组而不是 1d 传入时(甚至当 python 列表作为 1d 而不是 2d 传入时)。 So if we have所以如果我们有

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

then obviously if you try to index this then you will get arrays out (if you use item you do not).那么显然,如果您尝试对其进行索引,那么您将获得数组(如果您使用 item,则不会)。 this same thing also applies to standard python lists.同样的事情也适用于标准 python 列表。

Sorry about the confusion.很抱歉造成混乱。

Original原创

I am trying to form a new numpy array from something that may be a numpy array or may be a standard python list.我正在尝试从可能是 numpy 数组或可能是标准 python 列表的东西形成一个新的 numpy 数组。

for example例如

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]])

Now I would like to form a function such that I can make y easily.现在我想形成一个函数,以便我可以轻松地使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]])

This works great and I can now write (assuming the above function is included)这很好用,我现在可以编写(假设包含上述功能)

import numpy as np

x=[2, 3, 1]

y = skew(x)

However, I would also like to be able to call skew on existing 1d or 2d numpy arrays.但是,我也希望能够在现有的一维或二维 numpy 数组上调用 skew。 For instance例如

import numpy as np

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

y = skew(x)

Unfortunately, doing this returns a numpy array where the elements are also numpy arrays, not python floats as I would like them to be.不幸的是,这样做会返回一个 numpy 数组,其中元素也是 numpy 数组,而不是我希望它们是的 python 浮点数。

Is there an easy way to form a new numpy array like I have done from something that is either a python list or a numpy array and have the result be just a standard numpy array with floats in each element?有没有一种简单的方法来形成一个新的 numpy 数组,就像我从 python 列表或 numpy 数组中所做的那样,结果只是一个标准的 numpy 数组,每个元素都带有浮点数?

Now obviously one solution is to check to see if the input is a numpy array or not:现在显然一种解决方案是检查输入是否为 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]])

however, it gets very tedious having to write these instance checks all over the place.然而,必须到处编写这些实例检查是非常乏味的。

Another solution would be to cast everything to an array first and then just use the array call另一种解决方案是首先将所有内容转换为数组,然后仅使用数组调用

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]])

but I feel like this is inefficient as it requires creating a new copy of vector (in this case not a big deal since vector is small but this is just a simple example).但我觉得这是低效的,因为它需要创建一个新的 vector 副本(在这种情况下没什么大不了的,因为 vector 很小,但这只是一个简单的例子)。

My question is, is there a different way to do this outside of what I've discussed or am I stuck using one of these methods?我的问题是,在我讨论的内容之外是否有其他方法可以做到这一点,或者我是否坚持使用其中一种方法?

You can implement the last idea efficiently using numpy.asarray() :您可以使用numpy.asarray()有效地实现最后一个想法:

vector = np.asarray(vector)

Then, if vector is already a NumPy array, no copying occurs.然后,如果 vector 已经是一个 NumPy 数组,则不会发生复制。

You can keep the first version of your function and convert the numpy array to list :您可以保留函数的第一个版本并将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]])

This is not an optimal solution but is a very easy one.这不是最佳解决方案,但非常简单。 You can just convert the vector into list by default.默认情况下,您可以将向量转换为列表。

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

Arrays are iterable.数组是可迭代的。 You can write in your skew function:您可以在 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]])

In any case your methods ended with 1st dimension elements being numpy arrays containing floats.在任何情况下,您的方法都以第一维元素作为包含浮点数的 numpy 数组结束。 You'll need in any case a call on the 2nd dimension to get the floats inside.在任何情况下,您都需要调用第 2 维来获取浮点数。

Regarding what you told me in the comments, you may add an if condition for 2d arrays:关于您在评论中告诉我的内容,您可以为二维数组添加 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]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM