我有一个从第三方类继承的数据结构,该类重载__getitem__
,返回一个元组。你知道吗
现在,我在其他地方编写了代码,涉及将这些对象的集合附加到numy数组:
class ThirdPartyThing:
def __init__(self, size):
self.size = size
def __len__(self):
return self.size
def __getitem__(self, key):
return (self, key)
def __iter__(self):
return zip([self] * self.size, range(self.size))
class MyThing(ThirdPartyThing):
pass
x = numpy.array([], dtype = MyThing, ndmin = 1)
temp = [MyThing(1) for _ in range(5)]
x = numpy.append(x, temp)
当我这样做的时候,我所期望的是一个Numpy数组,有五个类型为MyThing
的对象,但是我得到的是一个一维数组,如下所示:
[MyThing(), 0, MyThing(), 0, MyThing(), 0, MyThing(), 0, MyThing(), 0]
它的长度是10,其中其他元素都是整数。你知道吗
根据the docs,append
如果axis
没有定义,那么append
会尝试展平数组,但在我的例子中,定义axis并没有什么区别。有没有办法避免这个陷阱?你知道吗
更新
仔细检查之后,我发现基类重载了__len__
。我想这就是问题的根源。你知道吗
你的文章的准确副本:
至于
np.append
,其代码是:所以对于一个轴,它就是
concatenate
。如果没有它,则确保两个参数都是1d你的
x
是(0,)形状,你的temp
是一个5元素列表,它的数组变成(5,)形状,结果是(5,)我看不出有什么问题。
np.append
中的“扁平化”不会影响代码。但正如我所说,我不喜欢np.append
。它混淆了太多的新用户,而且是不需要的。直接使用concatenate
。你知道吗还包括
ThirdPartyThing
类的代码,但不要使用它。你知道吗给
MyThing
一个报告:并定义不同的
temp
:现在我们看到
append
ravels的效果:(3,2)
temp1
在加入(0,)x
之前变成(6m,)
。你知道吗添加
axis=0
不起作用,因为维数不同。你知道吗使用您编辑的代码:
或者用我的报告:
加上
axis=0
仍然可以无论您如何构造它,尝试将(0,)形状数组与(3,1,2)形状数组连接需要进行一些调整。你知道吗
但是为什么要加入这两个数组呢?(0,)形状数组最初是从哪里来的?你知道吗
构建列表的方式是问题的根源:
但是
np.array([MyThing(2),MyThing(3)])
会导致某种无限循环。你知道吗但是回到
append
的问题。通常,在迭代地构建数组时,我们建议在列表中收集值(list append
非常快),并在末尾执行一个数组构造(使用np.array
、np.stack
和/或np.concatenate
)。你知道吗不建议以迭代方式进行连接。它比较慢,并且在创建有效的起始“空”数组时出现问题。你的
x
看起来就像一个空的启动者。np.append
给出了一种错误的感觉,即这种iteative数组构造与list-append方法一样好。不是。这就是我不喜欢np.append
的部分原因。使用concatenate
时,至少必须直接解决数组维度的差异。而且concatenate
需要一个列表,而不仅仅是两个参数。所以它在循环之外工作。你知道吗对于
len
和iter
,ThirdPartyThing
(通过继承MyThing
)是一个iterable。np.array
从这些东西的列表构造数组时,也会尝试对它们进行迭代(与使用列表时相同)。你知道吗我可以创建一个空的对象数组,并分别填充它,而不是从一个
MyThing
列表生成数组。现在我得到了这些对象的“干净”数组:甚至
只是不要把清单给
np.array
!你知道吗这种
temp
可以通过多种方式连接:相关问题 更多 >
编程相关推荐