ast*_*rog 9 python arrays numpy class
我最近在使用eg创建Numpy对象数组时遇到了问题
a = np.array([c], dtype=np.object)
Run Code Online (Sandbox Code Playgroud)
其中c是某个复杂类的实例,在某些情况下,Numpy尝试访问该类的某些方法.但是,做:
a = np.empty((1,), dtype=np.object)
a[0] = c
Run Code Online (Sandbox Code Playgroud)
解决了这个问题.我很好奇内部这两者之间的区别.为什么在第一种情况下Numpy会尝试访问某些属性或方法c
?
编辑:为了记录,这里是演示该问题的示例代码:
import numpy as np
class Thing(object):
def __getitem__(self, item):
print "in getitem"
def __len__(self):
return 1
a = np.array([Thing()], dtype='object')
Run Code Online (Sandbox Code Playgroud)
这打印出getitem
两次.基本上如果__len__
在类中存在,那么这就是人们可能遇到意外行为的时候.
don*_*mus 11
在第一种情况下a = np.array([c], dtype=np.object)
,numpy对预期数组的形状一无所知.
例如,当您定义时
d = range(10)
a = np.array([d])
Run Code Online (Sandbox Code Playgroud)
那么你期望numpy根据长度来确定形状d
.
因此,在您的情况下,numpy将尝试查看是否len(c)
已定义,如果已定义,则访问c
via 的元素c[i]
.
您可以通过定义诸如的类来查看效果
class X(object):
def __len__(self): return 10
def __getitem__(self, i): return "x" * i
Run Code Online (Sandbox Code Playgroud)
然后
print numpy.array([X()], dtype=object)
Run Code Online (Sandbox Code Playgroud)
产生
[[ x xx xxx xxxx xxxxx xxxxxx xxxxxxx xxxxxxxx xxxxxxxxx]]
Run Code Online (Sandbox Code Playgroud)
相反,在你的第二种情况下
a = np.empty((1,), dtype=np.object)
a[0] = c
Run Code Online (Sandbox Code Playgroud)
然后形状a
已经确定.因此numpy可以直接分配对象.
然而,在某种程度上,这是正确的,因为它a
是一个向量.如果已使用不同的形状定义,则仍将进行方法访问.例如,下面仍然会调用___getitem__
一个类
a = numpy.empty((1, 10), dtype=object)
a[0] = X()
print a
Run Code Online (Sandbox Code Playgroud)
回报
[[ x xx xxx xxxx xxxxx xxxxxx xxxxxxx xxxxxxxx xxxxxxxxx]]
Run Code Online (Sandbox Code Playgroud)