numpy.ndarray:转换为"普通"类

max*_*max 6 python numpy wrapper python-3.x

[Python 3]

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

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

class Array(numpy.ndarray):
  def __init__(size):
    # What do here?
Run Code Online (Sandbox Code Playgroud)

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

问题:

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

  2. 定义class Array我需要的最佳方法是什么?我应该只手动填充ndarray零,还是有任何方法可以重用该zeros功能?

Phi*_*ipp 7

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

  1. 与Matlab兼容/类似,其中函数类似于zerosones最初来自.
  2. 全局工厂功能编写快速且易于理解.应该怎样构造函数的语义是,例如,你会怎样表达一个简单的zeros或者emptyones有一个单独的构造?事实上,这种工厂功能很常见,在其他编程语言中也是如此.

定义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))
Run Code Online (Sandbox Code Playgroud)

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


jfs*_*jfs 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
Run Code Online (Sandbox Code Playgroud)

  • @Sven Marnach:前提是OP发现`ndarray`很烦人.委托是一种更灵活的方法来更改类接口而不是继承.代码不是最终解决方案,但它只是一个仅仅是一个框架示例,允许扩展它以使用黑名单,白名单等方法.我同意模块级功能.代码显示*如何*你可以做到; 它并不主张这是明智之举. (2认同)