numpy.ndarray:转换为“正常”类

时间:2011-01-21 10:18:54

标签: python numpy python-3.x wrapper

[Python 3]

我喜欢ndarray,但我觉得使用起来很烦人。

这是我面临的一个问题。我想编写将继承ndarray的大部分功能的class Array,但只有一种方法可以实例化:作为一个特定大小的零填充数组。我希望写:

class Array(numpy.ndarray):
  def __init__(size):
    # What do here?

我想使用一些参数调用super().__init__来创建零填充数组,但由于ndarray使用全局函数numpy.zeros(而不是构造函数)来创建一个零填充数组。

问题:

  1. 为什么ndarray在很多情况下使用全局(模块)函数而不是构造函数?如果我试图在面向对象的环境中重复使用它,那将是一个很大的烦恼。

  2. 定义class Array我需要的最佳方法是什么?我应该只用零手动填充ndarray,还是有办法重用zeros函数?

3 个答案:

答案 0 :(得分:7)

  

为什么ndarray在很多情况下使用全局(模块)函数而不是构造函数?

  1. 与Matlab兼容/类似,其中zerosones等函数最初来自。
  2. 全球工厂功能易于编写且易于理解。构造函数的语义应该是什么,例如:你如何用一个构造函数表达一个简单的zerosemptyones?事实上,这种工厂功能非常普遍,也适用于其他编程语言。
  3.   

    定义class Array我需要的最佳方式是什么?

    import numpy
    
    class Array(numpy.ndarray):
        def __new__(cls, size):
            result = numpy.ndarray.__new__(Array, size)
            result.fill(0)
            return result
    arr = Array(5)
    
    def test(a):
        print type(a), a
    
    test(arr)
    test(arr[2:4])
    test(arr.view(int))
    
    arr[2:4] = 5.5
    
    test(arr)
    test(arr[2:4])
    test(arr.view(int))
    

    请注意,这是Python 2,但只需要很少的修改即可使用Python 3。

答案 1 :(得分:6)

如果你不喜欢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

答案 2 :(得分:4)

ndarray的继承有点棘手。 ndarray甚至没有方法__init(self, )___,因此无法从子类调用它,但有理由这样做。请参阅subclassing的numpy文档。

顺便问一下,您可以更具体地了解您的特殊需求吗?根据自己的需要烹饪类(利用ndarray)仍然很容易,但ndarray的子​​类传递所有numpy机制是完全不同的问题。

似乎我无法评论自己的帖子,奇怪
@Philipp:它将被Python调用,但不会被numpy调用。有三种方法可以实例化ndarray,并且该文档中提供了如何处理所有案例的指南。