如何在numpy中创建一个空列表网格,并接受'追加?

时间:2017-04-18 23:08:48

标签: python numpy append attributeerror

我正在尝试使用numpy.append,但出现了问题而且它不再对我有所帮助。有人可以解释我收到错误的原因吗?

>>> np.array([[], [], []]).shape
(3, 0)

>>> a=[[], [], []]
>>> a[1].append(3)
>>> a
[[], [3], []]

>>> b=np.array(a)
>>> b[0].append(3)
array([[3], [3], []], dtype=object)

这对我来说是合乎逻辑的,但是当我尝试以下操作时它会停止工作。

>>> c=np.array((3,0),dtype=object)
>>> c[0].append(3)
AttributeError: 'int' object has no attribute 'append'

????
>>> np.empty((3,1))[0].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'

>>> np.empty((3,0))[1].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'

>>>np.empty((6,1),dtype=object)[0].append(3)
AttributeError: 'numpy.ndarray' object has no attribute 'append'

解决:How to create a numpy array of lists?

3 个答案:

答案 0 :(得分:1)

不要只看形状;检查dtype,如果是object,则检查元素的性质

In [282]: np.array([[], [], []])
Out[282]: array([], shape=(3, 0), dtype=float64)

2d浮点阵列。 np.array尝试创建一个多维数组;只有当它不能做到这一点时才会产生一个对象数组。

In [283]: b=np.array([[],[3],[]])
In [284]: b
Out[284]: array([[], [3], []], dtype=object)

这里有3个子列表有不同的大小,所以不能制作2d数组;结果是一个对象数组,其中对象是列表,并具有append方法。

In [286]: c=np.array((3,0), object)
In [287]: c
Out[287]: array([3, 0], dtype=object)

这是一个(2,)对象数组; 2个元素是数字。数字没有附加方法。

In [288]: np.empty((3,1))
Out[288]: 
array([[ 0.],
       [ 0.],
       [ 0.]])

(3,1)浮点阵列。数字或数组没有附加方法。

In [289]: np.empty((3,0))
Out[289]: array([], shape=(3, 0), dtype=float64)

另一个2d浮点阵列

In [290]: np.empty((6,1),object)
Out[290]: 
array([[None],
       [None],
       [None],
       [None],
       [None],
       [None]], dtype=object)

dd对象的2d数组。在这种情况下,它们被初始化为None。再没有附加方法。

有关制作列表数组的更多信息

dimensions of array of arrays in numpy

How to keep numpy from broadcasting when creating an object array of different shaped arrays

In [305]: d=np.empty((3,),object)
In [306]: d
Out[306]: array([None, None, None], dtype=object)
In [307]: d.fill([])
In [308]: d
Out[308]: array([[], [], []], dtype=object)   # array of lists
In [309]: d[0].append([1,2,3])
In [310]: d
Out[310]: array([[[1, 2, 3]], [[1, 2, 3]], [[1, 2, 3]]], dtype=object)

但是oops - 那些列表都是相同的对象(指针):(我必须在每个元素中添加一个不同的列表。现在我可以单独附加它们。

In [311]: d[...]=[[],[1,2,3],[2]]
In [312]: d
Out[312]: array([[], [1, 2, 3], [2]], dtype=object)
In [313]: d[0].append([2,3])
In [314]: d
Out[314]: array([[[2, 3]], [1, 2, 3], [2]], dtype=object)

我认为你必须咬紧牙关并使用列表来初始化列表的对象数组。没有捷径:

In [319]: d=np.empty((3,),object)
In [320]: d[...]=[[] for _ in range(3)]
In [321]: d
Out[321]: array([[], [], []], dtype=object)
In [323]: d
Out[323]: array([[], [3], []], dtype=object)

答案 1 :(得分:1)

首先,当有人正确回答问题时,请停止更新您的问题。当你准备好时,接受/提出答案并提出新问题。 SO是一个Q& A网站,旨在帮助未来的访问者查看您的问题,而不仅仅是您。完全根据自己的利益改变上下文,使所有好的答案无效,至少可以说是失败了这个网站的目的。

其次,np.array([[], [3], []])dtype=object结尾,因为它是一个不规则的数组。 [[], [], []][[3], [3], [3]]在所有维度的所有元素中具有统一的长度,将生成数值数组。

np.zeros((6,),dtype=object)生成一个空数组的对象引用(包含NULL)。当您使用[]填充它时,您将在每个元素中添加对相同 python list的引用。 numpy不知道您传递给ndarray.fill的对象,因此它不会像您期望的那样为每个元素调用list类型的构造函数。它只复制你传递六次的引用。之后,应该清楚为什么更改该列表的内容会使所有数组元素都显示已更改。

答案 2 :(得分:0)

我知道这是一个非常不寻常的用例,但是实际上,在每个单元格中拥有一个包含列表的ndarray会非常方便。 Imho numpy应该允许将lambda函数传递给fill方法。但是要达到您想要的目的,这就是我要做的:

m = np.empty((12, 12), dtype=object)
for i in np.ndindex(m.shape): m[i] = []