Python numpy.ndarray:转换为“a”;“正常”;班
[Python 3] 我喜欢Python numpy.ndarray:转换为“a”;“正常”;班,python,numpy,python-3.x,wrapper,Python,Numpy,Python 3.x,Wrapper,[Python 3] 我喜欢ndarray,但我觉得用起来很烦人 我面临一个问题。我想编写类数组,它将继承ndarray的大部分功能,但只有一种实例化方法:作为特定大小的零填充数组。我希望写: class Array(numpy.ndarray): def __init__(size): # What do here? 我想用一些参数调用super()。\uuuu init\uuu来创建一个零填充数组,但它不起作用,因为ndarray使用一个全局函数numpy.zeros(而不是构
ndarray
,但我觉得用起来很烦人
我面临一个问题。我想编写类数组
,它将继承ndarray的大部分功能,但只有一种实例化方法:作为特定大小的零填充数组。我希望写:
class Array(numpy.ndarray):
def __init__(size):
# What do here?
我想用一些参数调用super()。\uuuu init\uuu
来创建一个零填充数组,但它不起作用,因为ndarray
使用一个全局函数numpy.zeros
(而不是构造函数)来创建一个零填充数组
问题:
类数组
的最佳方法是什么?我应该用零手动填充ndarray
,还是有办法重用zeros
函数zero
或ones
最初来自Matlab零
或空
或一
?事实上,这种工厂函数在其他编程语言中也很常见类数组
的最佳方法是什么
请注意,这是Python2,但使用Python3只需稍作修改。如果您不喜欢
ndarray
接口,则不要继承它。您可以定义自己的接口,并将其余接口委托给ndarray和numpy
import functools
import numpy as np
class Array(object):
def __init__(self, size):
self._array = np.zeros(size)
def __getattr__(self, attr):
try: return getattr(self._array, attr)
except AttributeError:
# extend interface to all functions from numpy
f = getattr(np, attr, None)
if hasattr(f, '__call__'):
return functools.partial(f, self._array)
else:
raise AttributeError(attr)
def allzero(self):
return np.allclose(self._array, 0)
a = Array(10)
# ndarray doesn't have 'sometrue()' that is the same as 'any()' that it has.
assert a.sometrue() == a.any() == False
assert a.allzero()
try: a.non_existent
except AttributeError:
pass
else:
assert 0
ndarray的继承有点棘手
ndarray
甚至没有方法\uuuu init(self,)\uuuuu
,因此无法从子类调用它,但这是有原因的。请参阅的numpy文档
顺便问一下,你能更具体地说明你的特殊需要吗?根据您自己的需要编写一个类(使用ndarray)仍然很容易,但是ndarray的一个子类通过所有numpy机制是完全不同的问题
似乎我不能评论我自己的帖子,奇怪的@Philipp:它将由Python调用,但不会由numpy调用。实例化ndarray有三种方法,该文档中给出了如何处理所有情况的指导原则。我不明白您为什么要创建自己的类。与
numpy.zeros()
工厂函数相比,它有什么优势?如果你不喜欢这个名字,就把它重命名,比如create\u array=numpy.zeros
。我不再确定它有什么优势。也许我只是不习惯工厂的功能。我必须考虑一下。@Sven Marnach:我找到了几个关于这个一般主题的链接:没有特定于Python的内容,但是其他语言的一般评论似乎适用。就我所知,工厂的功能并没有什么坏处(除了我个人的喜好)。ndarray
构造函数的shape
参数可能只是一个整数而不是元组。2. <默认值为code>dtype=float。3.在Python 3中,在本例中可以省略super()
的参数。结合这些注释,构造函数的前两行缩减为super()。(构造函数签名通常没有文档记录。)@Philipp:它记录在类的docstring中,而不是构造函数本身。但这实际上是文档所属的地方。@Sven:我的意思是,文档说shape
必须是一个元组,而不是说dtype
默认为float
。我好像错过了这个文档。但是为什么在我的示例中调用\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。你说得对,对ndarray子类化太难了。我将在@J.F.Sebastian中采用容器方法。非常简洁。我假设所有numpy
全局函数在使用ndarray
参数调用时与ndarray
的同名实例方法具有相同的语义。要更改为Python 3,我只需从类定义中删除(对象)
,对吗?[并不是说离开它会导致问题。]@max:代码在2.x和Python3上都可以正常工作,没有任何更改。我似乎遗漏了一些东西。您不从ndarray
派生,但如果请求了任何属性,则首先尝试从ndarray
实例获取属性。首先,从ndarray
派生不是更容易吗?您仍然可以添加魔法,将numpy中的模块级函数添加为方法,但我认为这也不是一个好主意,因为它们中的大多数已经是方法了,其余的作为方法没有意义(只有极少数例外)。@Sven Marnach:前提是OP发现ndarray
使用起来很烦人。委派是一种比继承更灵活的更改类接口的方法。代码不是最终的解决方案,但它只是一个框架示例,允许扩展它以使用黑名单、白名单等方法。我同意模块级函数。代码显示了如何做到这一点;它并不主张这样做是明智的。
import functools
import numpy as np
class Array(object):
def __init__(self, size):
self._array = np.zeros(size)
def __getattr__(self, attr):
try: return getattr(self._array, attr)
except AttributeError:
# extend interface to all functions from numpy
f = getattr(np, attr, None)
if hasattr(f, '__call__'):
return functools.partial(f, self._array)
else:
raise AttributeError(attr)
def allzero(self):
return np.allclose(self._array, 0)
a = Array(10)
# ndarray doesn't have 'sometrue()' that is the same as 'any()' that it has.
assert a.sometrue() == a.any() == False
assert a.allzero()
try: a.non_existent
except AttributeError:
pass
else:
assert 0