【问题标题】:Subclassing and extending numpy.ndarray子类化和扩展 numpy.ndarray
【发布时间】:2014-12-01 05:14:17
【问题描述】:

我需要一些基本的数据类表示,并且我想使用现有的 numpy 类,因为它们已经提供了很好的功能。

但是,我不确定这是否是这样做的方法(尽管到目前为止它仍然有效)。所以这里是一个例子:

Position 类应该像一个简单的numpy.array,但它应该将属性.x.y.z 映射到三个数组组件。我用初始数组覆盖了 __new__ 方法,该方法返回 ndarray。为了允许访问和修改数组,我为每个属性定义了属性和设置器。

import numpy as np


class Position(np.ndarray):
    """Represents a point in a 3D space

    Adds setters and getters for x, y and z to the ndarray.

    """
    def __new__(cls, input_array=(np.nan, np.nan, np.nan)):
        obj = np.asarray(input_array).view(cls)
        return obj

    @property
    def x(self):
        return self[0]

    @x.setter
    def x(self, value):
        self[0] = value

    @property
    def y(self):
        return self[1]

    @y.setter
    def y(self, value):
        self[1] = value

    @property
    def z(self):
        return self[2]

    @z.setter
    def z(self, value):
        self[2] = value

然而,对于这样一个基本逻辑来说,这似乎有点太多的代码,我想知道我是否以“正确”的方式来做。我还需要一堆其他类,比如Direction,它们会有很多其他功能(变化时自动规范等),在我开始集成 numpy 之前,我想我问你……

【问题讨论】:

  • 到目前为止,您所拥有的看起来很像 pandas.dataframe(不是我自己与他们合作过的......)。否则它看起来很标准。
  • 哪个对你更重要,代表一个点,还是用数千个点做数学?我会开始使用(N,3) 数组(或(3,N)),然后编写一些函数来访问选定的列。
  • 对我来说最重要的是如何正确扩展ndarray,如标题所示。 Position 只是一个小例子。

标签: python numpy subclassing multidimensional-array


【解决方案1】:

我认为 ndarray 在这里是错误的选择,你可能想要一个简单的命名元组。

>>> import collections
>>> Position = collections.namedtuple('Positions', 'x y z')
>>> p = Position(1, 2, 3)
>>> p
Positions(x=1, y=2, z=3)

你可以这样解包

>>> x, y, z = p
>>> x, y, z
(1, 2, 3)
>>>

【讨论】:

  • 我真的很想要 ndarray 功能,比如点积、矩阵运算和所有其他 numpy 附加功能。扩展namedtuple 以支持它们需要更多的工作。
  • 这取决于您的情况,但命名元组是专门为类似于您上面概述的示例的情况设计的。我看不出 numpy 的 view 功能对三项数组有何用处。您可以使用带有 map/reduce/comprehensions 的普通 python 来处理产品,例如Position(*map(lambda x: x * 3, p))。有关更多示例,请参阅docs.python.org/2/library/itertools.html
  • 我的分析中有数十万个位置、方向等以及许多计算以及矩阵变换。大多数算法都需要 numpy 数组,这就是为什么在我的情况下它必须类似于 numpy。感谢您的回答,但这并不能解决我的特殊问题。
  • @septi:数十万个 3 元素 numpy 数组是缓慢的秘诀。如果您关心性能,则需要将数据重新组织成几个大型 numpy 数组,理想情况下,将您的计算表示为在整个大型数组上完成。否则,您的代码实际上会比使用 Python 列表(或命名元组)慢。
  • 我只是想强调一下,我已经非常嵌套在一个 numpy 环境中了。当然,在某些时候可能会有一个优化过程,但目前我尝试使用“已经存在”的任何东西,并且大部分东西都是对数组的 linalg 操作。顺便说一句。 3D-Position 只是一个例子。不过谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 2016-12-14
  • 2018-12-30
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多