4

我主要用numpy做数据分析,对底层程序不太了解,所以这可能很明显。

我不明白通过简单地分配属性来设置属性与调用就地更改该属性的方法之间的区别。你可以同时做的例子是:

In [1]: import numpy as np

In [2]: a = np.array([[1, 2, 3],
   ...:               [4, 5, 6]])

In [3]: a.shape
Out[3]: (2, 3)

In [4]: a.reshape(3,2)
Out[4]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

In [5]: a
Out[5]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [6]: a.resize(3,2)

In [7]: a
Out[7]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

In [8]: a.shape = (6,)

In [9]: a
Out[9]: array([1, 2, 3, 4, 5, 6])

In [10]: a.__setattr__('shape',(3,2))

In [11]: a
Out[11]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

我不明白 input68. 显然,两者都更改了a.shape适当的属性,而不是像在4. 他们都只打电话a.__setattr__()10?如果是这样,为什么它们都存在?

(我知道a.resize()有额外的容量来增加或减少分配的内存,但我在这里没有使用它——这种重复性是否只存在于该方法增加了一些其他容量?)

4

2 回答 2

2

8 中的示例实际上称为property,python 允许您在 2.1+ 版本中访问它。

例如

@property
def shape(self):
    """I'm the 'shape' property."""
    return self._shape

@shape.setter
def shape(self, value):
    self._shape = value

__setattr__调用一个setter

x.__setattr__('shape', value) 

相当于(查看上面的属性设置器)。

x.shape = value

底层逻辑总是调用一个修饰函数。

于 2013-02-25T18:34:03.237 回答
1

我已经多次阅读您的问题,并认为我可以解决所有问题:

a.reshape(3,2)
# returns a new array

a.resize(3,2)
# returns None, operates on the same array
# (equivalent to modifying ndarray.shape here since no. of elements is unchanged)

a.shape = (6,)
# operates on the same array, uses property trick to hide detailed 
# setter logic behind normal attribute access.  
# note the parens are unnecessary here - equivalent is a.shape = 6,
# NOT equivalent to a = a.reshape(6,), which would change the id(a)

a.__setattr__('shape',(3,2))
# just an ugly way of doing a.shape = 3,2

您的主要问题似乎是关于改变数组形状的方法的非唯一性。

显然,两者都更改了 a.shape 属性,而不是像 4 中那样返回重塑的对象

是的。或者更准确地说,两者都更改了数组(并且shape“属性”返回的值因此被修改)。

他们都只a.__setattr__()像10那样打电话吗?

他们并不一定要调用a.__setattr__(...)。他们可以改为更改一些内部self._shape变量,它仍然可以更改a.shape.

__setattr__您可以通过创建自己的类来查看实际使用的人,例如:

class my_ndarray(np.ndarray):
    def __setattr__(self, name, value):
        print '__setattr__ called with name={}, value={}'.format(name, value)
        super(my_ndarray, self).__setattr__(name, value)

a_ = my_ndarray(a.shape)
a_[:] = a

在这种情况下,答案是既不a_.resize也不a_.reshape使用__setattr__

如果是这样,为什么它们都存在?

当元素的数量不同时,它resize可以做的不仅仅是重塑,这对我来说是足够的理由。当您需要做的就是使用 reshape 时,使用 resize 会很奇怪,但是当您“可能”使用 reshape 时,为什么 numpy(它应该是高性能的)会费心警告您或人为地限制您使用 resize反而?

如果您担心明显违反python #13 的 zennumpy这不是寻找一致性的最佳位置。只需比较np.eyenp.identity,例如!什么是 numpythonic 并不总是 pythonic。

于 2013-02-27T01:54:03.487 回答