如何在Numpy中创建一个(有时)不规则的数组?



在Numpy中,我想创建一个整数数组(或列表)的数组。每个单独的数组都是一组索引。这些单独的数组通常具有不同的长度,但有时它们具有相同的长度。

当长度不同时,我可以创建数组

test = np.array([[1,2],[1,2,3]],dtype=object)

当我这样做时,test[0]是一个整数列表,我可以毫无问题地使用other_array[test[0]]

然而,当test恰好有相同大小的条目时,我做

test = np.array([[1,2],[1,3]], dtype=object)

test[0]是dtype为object的Numpy数组。当我使用other_array[test[0]]时,我得到一个错误,arrays used as indices must be of integer (or boolean) type.

下面是一个完整的例子:

other_array = np.array([0,1,2,3])
test1 = np.array([[1,2],[1,2,3]], dtype=object)
print(other_array[test1[0]]) #this works
test2 = np.array([[1,2],[1,3]], dtype=object)
print(other_array[test2[0]]) #this fails

我在这个问题上发现的唯一方法是检查test在创建它之前是否会破损,并在碰巧拥有所有相同大小的数组时使用dtype=int。这似乎效率低下。是否有一种通用的方法来创建整数数组的数组,有时是粗糙的,有时不是没有检查褴褛?

为了一致地创建对象类型数组,您需要初始化一个正确大小的数组,然后将列表赋值给它:

In [86]: res = np.empty(2, object)
In [87]: res
Out[87]: array([None, None], dtype=object)
In [88]: res[:] = [[1,2],[1,2,3]]
In [89]: res
Out[89]: array([list([1, 2]), list([1, 2, 3])], dtype=object)
In [90]: res[:] = [[1,2],[1,3]]
In [91]: res
Out[91]: array([list([1, 2]), list([1, 3])], dtype=object)

你不能这样赋值(2,n)数组:

In [92]: res[:] = np.array([[1,2],[1,3]])
Traceback (most recent call last):
File "<ipython-input-92-f05200126d48>", line 1, in <module>
res[:] = np.array([[1,2],[1,3]])
ValueError: could not broadcast input array from shape (2,2) into shape (2,)

,但数组列表可以工作:

In [93]: res[:] = [np.array([1,2]),np.array([1,3])]
In [94]: res
Out[94]: array([array([1, 2]), array([1, 3])], dtype=object)
In [95]: res[:] = list(np.array([[1,2],[1,3]]))
In [96]: res
Out[96]: array([array([1, 2]), array([1, 3])], dtype=object)

基本要点是,多维数字dtype数组是首选类型,而对象dtype是一个后备选项,特别是在使用np.array()时。对于某些数组形状的组合,np.array将引发错误,而不是创建对象dtype。因此,创建并填充是唯一一致的操作。

你的test1, test2

Out[97]: array([list([1, 2]), list([1, 2, 3])], dtype=object)
In [98]: np.array([[1,2],[1,2,3]], dtype=object)[0]
Out[98]: [1, 2]
In [99]: np.array([[1,2],[1,3]], dtype=object)
Out[99]: 
array([[1, 2],
[1, 3]], dtype=object)
In [100]: np.array([[1,2],[1,3]], dtype=object)[0]
Out[100]: array([1, 2], dtype=object)
In [103]: np.array([[1,2],[1,3]])[0]
Out[103]: array([1, 2])

但是我想知道是否有必要从列表的列表中创建一个数组。如果您只是将它们用作索引,则为列表建立索引也一样好:

In [105]: [[1,2],[1,3]][0]
Out[105]: [1, 2]
In [106]: [[1,2],[1,2,3]][0]
Out[106]: [1, 2]

注意np.nonzero(又名np.where)返回一个数组元组。这可以直接用作多维索引。np.argwheretranspose应用于该元组,创建一个(n,ndim)数组。这看起来不错,但不能(直接)用于索引。

你可能有一个很好的理由使用numpy, idk。要想在失败的地方解决问题,你可以先把它打开。这适用于粗糙和均匀。您也不需要使用任何检查器。

test2 = np.array([[1,2],*[1,3]], dtype=object)
print(other_array[test2[0]]) #this works

相关内容

最新更新