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]])

6入力との違いがわかりません8。のように再形成されたオブジェクトを返すのではなく、明らかに両方ともその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

あなたの主な質問は、配列の形状を変更するメソッドの非一意性についてのようです。

4 のように再形成されたオブジェクトを返すのとは対照的に、どちらも明らかに a.shape 属性を適切に変更します。

はい。より正確には、両方とも配列をその場で変更します (shape結果として、「属性」によって返される値が変更されます)。

どちらも 10 のように呼び出すだけa.__setattr__()ですか?

を呼び出す必要はありません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 を使用するのは奇妙ですが、なぜ numpy (高性能であると想定されている) が警告を表示したり、reshape を使用できる場合に resize の使用を人為的に制限したりする必要があるのでしょうか。代わりは?

明らかに python #13の zen に違反していることを懸念している場合はnumpy、一貫性を探すのに最適な場所ではありません。たとえば、np.eyeとを比較するだけです。np.identitynumpythonic とは、常に pythonic とは限りません。

于 2013-02-27T01:54:03.487 に答える