2

以下の点で困っています。

ndarray サブクラスを作成し、このサブクラスの新しいインスタンスに形状 (-1,3) を適用したいと思います。明示的なコンストラクター、ビューのキャスト、またはテンプレートからのいずれであってもかまいません。

私はたくさんのことを試しましたが、どれもうまくいかないようです。根底にあるプロセスを完全に把握していないと思います。どんな助けでも大歓迎です!

import numpy as np

class test(np.ndarray):
def __new__(cls, *args, **kwargs):
    return np.ndarray.__new__(cls, *args, **kwargs)

def __array_finalize__(self, obj):

#        self.resize(-1,3)
#        self.reshape(-1,3)
#        self=self.reshape(-1,3)
        np.reshape(self,(-1,3))

a=np.array([1,2,3])
b=a.view(test)
c=test(a)
d=a.reshape(-1,3)
print '+++++++'
print a.shape,a
print '+++++++'
print b.shape,b
print '+++++++'
print c.shape,c
print '+++++++'
print d.shape,d

私がやろうとしていることを明確にするために:

一般的に 3D として扱いたいベクトル フィールドがあるため、(:,3) 形状と (-1,3) 形状のサイズ変更を行います。NumPyにすでに付属しているものを補完するために、本質的にいくつかの追加メソッドを実装するための純粋なオブジェクト指向ソリューションを探しています。

たとえば、私は純粋に ndarrays を使っていくつかのものを書き始めましたが、単に書くことができれば、コードははるかに読みやすくなります。

normalizedVector = ndarray.view(my3DVectorClass).normalize()

それよりも

normalizedVector = ndarray / ( sum(ndarray**2, axis=1)**0.5 )

2番目の問題:

  • 形状 (3,) または (:,3) 配列の正規化されたバージョンを求めているかどうかについて心配する必要がないようにしたいと思います。
  • クラスメソッドの実装内で純粋な線形代数の用語を使用できるようになり、メソッド定義内のインデックス付けとエラー/次元のチェックに煩わされる必要がなくなります。

my3DVectorClass のインスタンスのみを操作するように主張することもできると思いますが、すべての SciPy 機構を使用する場合は逆のビュー キャストを行う必要があります。少し肥大化したコード。

どういうわけか私の論理が間違っている可能性がある場合は、提案に感謝します。私はまだ、OOP と SciPy/NumPy の両方について学習曲線上にあります。

もう本当にありがとう!

マーカス

4

2 に答える 2

7

matrixクラスの実装方法を確認する必要があります。維持するために同様のトリックを行いますndims=2

しかし、私や他の多くの人は、そのような策略は価値があるよりも面倒だと考えています. このmatrixクラスは、通常のように部分的にしか動作しないため、過去に多くの問題を引き起こしてきましたndarray。代わりに関数を書くことを検討してください。上記のコード例は、次のように最も読みやすいものになりますnormalizedVector = normalize(ndarray)。オブジェクト指向スタイルを使用している場合でも、より多くのサブクラスを作成することが常に最適な設計であるとは限りません。

于 2013-02-20T09:53:55.283 に答える
0

reshape新しい形状でデータのビューを作成しようとします。それができない場合は、新しい形状でデータのコピーを作成します。ただし、元のオブジェクトは変更されません。形状をその場で変更するには、次のことができます。

self.shape = (-1, 3)

例えば:

>>> a = np.arange(9)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.reshape(a, (-1, 3)) # creates a view with the new shape
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> a # but the original object is unchanged
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a.shape = (-1, 3) # this modifies the original object
>>> a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

ただし、コピーを作成せずに形状を変更できない場合は、次のエラーが発生するため、注意が必要ですAttributeError

>>> a = np.arange(36).reshape(6, 6).T
>>> b = np.reshape(a, (-1, 3)) # creates a copy of the data in a
>>> a.shape = (-1, 3) # tries to reshape in-place, and fails
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: incompatible shape for a non-contiguous array
于 2013-02-19T21:02:28.920 に答える