我正在尝试使用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'
答案 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] = []