0

いくつかの属性を格納するクラスがあります。これらの属性は、内部にいくつかの浮動小数点数を持つ numpy 配列です。オブジェクトを作成するときにこの属性にアクセスできるようにします。私が望んでいないのは、属性の値を保持する外部変数に対して何らかの操作が行われた場合に、それらが変更されることです。

これは、ゲッター/セッターまたは他のタイプの変数を持つプロパティで行うのは簡単ですが、numpy 配列では失敗するようです。

私が知っているあらゆる種類の可能な解決策をテストする簡単なスクリプトを作成しました。整数属性では機能しますが、numpy 配列では失敗します。

これはテストクラスです:

class test_class:

    # Initialization
    def __init__(self, attribute1, attribute2, attribute3):

        self.attribute1 = attribute1
        self._attribute2 = attribute2
        self._attribute3 = attribute3

# Attribute 1 with getter and setter
    def get_attr1(self):
        return(self.attribute1)

    def set_attr1(self, value):
        self.attribute1 = value

    # Attribute 2 as a property with getter and setter
    def get_attr2(self):
        return(self._attribute2)

    def set_attr2(self, value):
        self._attribute2 = value

    attribute2 = property(get_attr2, set_attr2)

    # Attribute 3 as a property
    @property
    def attribute3(self):
        return(self._attribute3)

    @attribute3.setter
    def attribute3(self, value):
        self._attribute3 = value

整数を属性としてテストする:

test = test_class(10, 100, 1000)

print test.get_attr1()
print test.attribute2
print test.attribute3

a1 = test.get_attr1()
a2 = test.attribute2
a3 = test.attribute3

a1 += 5
a2 += 50
a3 += 500

print test.get_attr1()
print test.attribute2
print test.attribute3

属性が外部から変更されることなく、期待どおりに出力されます。

10
100
1000
10
100
1000

numpy 配列でテストする:

import numpy as np

test = test_class(np.array([10,20,30]), np.array([100,200,300]),   np.array([1000,2000,3000]))

print test.get_attr1()
print test.attribute2
print test.attribute3

a1 = test.get_attr1()
a2 = test.attribute2
a3 = test.attribute3

a1 += 5
a2 += 50
a3 += 500

print test.get_attr1()
print test.attribute2
print test.attribute3

出力が期待どおりではありません。値が変更されました:

[10 20 30]
[100 200 300]
[1000 2000 3000]
[15 25 35]
[150 250 350]
[1500 2500 3500]

ゲッター/セッターもプロパティもnumpy配列で機能しない場合、何ができるでしょうか?

編集:

さて、copy.deepcopy関数を使用してこの問題の解決策を見つけました。今では期待どおりに動作します。

属性定義:

from copy import deepcopy

class test_class:

    ...

    # Attribute 4 with getter and setter using deepcopy
    def get_attr4(self):
        return(deepcopy(self.attribute4))

    def set_attr4(self, value):
        self.attribute4 = value

テスト:

test = test_class(np.array([10,20,30]), np.array([100,200,300]), np.array([1000,2000,3000]), np.array([10000,20000,30000]))

...
print test.get_attr4()
...
a4 = test.get_attr4()
...
a4 += 5000
...
print test.get_attr4()

結果:

...
[10000 20000 30000]
...
[10000 20000 30000]
4

1 に答える 1

3

NumPy 配列は変更可能ですが、整数は変更できません。

>>> a = 1
>>> id(1)
4297261152
>>> a += 1
>>> id(a)
4297261184

id変更。

とは対照的に:

>>> arr = np.arange(5)
>>> d(arr)
4331954736
>>> arr += 10
>>> id(arr)
4331954736
>>> arr
array([10, 11, 12, 13, 14])

:idは同じままです。

a = test.get_attr1()またはを使用しても問題ありませんa = test.attribute2aほとんどすべてが Python で扱うオブジェクトであるため、得られる は Python オブジェクトです。一度取得すると、代入によって、またはメソッドからの戻り値としてa作成した方法は関係ありません(プロパティは、メソッド呼び出しのより適切な構文になります)。次に、オブジェクトの名前にすぎず、このオブジェクトを操作します。NumPy 配列のように変更可能な場合、通常は内部の値が変更されます。不変の場合、これは単に不可能です。a = 1a = test.get_attr1()a+=

これらのオブジェクトを変更したくない場合は、コピーを作成できます。通常、モジュールの助けを借りてcopy。NumPy 配列は、独自のコピー メソッドを提供します。

>>> arr2  = arr.copy()
>>> arr
array([10, 11, 12, 13, 14])
>>> arr2 += 100
>>> arr2
array([110, 111, 112, 113, 114])
>>>  arr
array([10, 11, 12, 13, 14]) 
于 2013-06-05T13:45:01.650 に答える