Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 子类化和扩展numpy.ndarray_Python_Numpy_Subclassing_Multidimensional Array - Fatal编程技术网

Python 子类化和扩展numpy.ndarray

Python 子类化和扩展numpy.ndarray,python,numpy,subclassing,multidimensional-array,Python,Numpy,Subclassing,Multidimensional Array,我需要一些基本的数据类表示,我想使用现有的numpy类,因为它们已经提供了很好的功能 然而,我不确定这是否是一种方法(尽管到目前为止它是有效的)。下面是一个例子: Position类应该像一个简单的numpy.array,但它应该将属性.x、.y和.z映射到三个数组组件。我重写了\uu new\uu方法,该方法返回带有初始数组的ndarray。为了允许访问和修改数组,我为每个数组定义了属性和setter import numpy as np class Position(np.ndarray

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

然而,我不确定这是否是一种方法(尽管到目前为止它是有效的)。下面是一个例子:

Position
类应该像一个简单的
numpy.array
,但它应该将属性
.x
.y
.z
映射到三个数组组件。我重写了
\uu new\uu
方法,该方法返回带有初始数组的
ndarray
。为了允许访问和修改数组,我为每个数组定义了属性和setter

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之前,我想问你…

我认为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)
>>>

到目前为止,您所拥有的看起来非常像pandas.dataframe(我自己并没有使用过它们…)。否则它看起来很标准。对你来说,哪一个更重要,代表一个点,还是用数千个点来做数学?我开始使用
(N,3)
数组(或
(3,N)
),并编写一些函数来访问选定的列。对我来说,最重要的是如何正确扩展
数组,正如标题所说。
Position
只是一个很小的例子。我非常想要
ndarray
功能,比如点积、矩阵运算和所有其他numpy额外功能。扩展
namedtuple
以支持它们需要做更多的工作。这取决于您的情况,但命名元组是专门为类似于您上面概述的示例的情况而设计的。我不认为numpy的视图功能对三项数组有什么用处。您可以使用带有map/reduce/comprehension的普通python来处理产品,例如
Position(*map(lambda x:x*3,p))
。更多例子请参见。在我的分析中,我得到了数十万个位置、方向等,以及许多计算和矩阵变换。大多数算法都需要numpy数组,这就是为什么在我的例子中它必须是类似numpy的。谢谢你的回答,但这并不能解决我的特殊问题。@septi:数十万个3元素numpy数组是缓慢的秘诀。如果您关心性能,则需要将数据重新组织为几个大的numpy数组,理想情况下,将计算表示为在整个大数组上完成。否则,您的代码实际上会比使用Python列表(或namedtuples)慢。当然,在某个时候可能会有一个优化过程,但目前我尝试使用“已经存在”的任何东西,大部分内容都是阵列上的linalg操作。顺便说一句,3D位置只是一个例子。不过,谢谢你。