ビルドしたいくつかの Matlab ライブラリを Python 環境に移動しようとしています。これまでに直面した最大の問題は、インデックス指定に基づく配列の動的割り当てです。たとえば、Matlab を使用して、次のように入力します。
x = [1 2];
x(5) = 3;
次のようになります。
x = [ 1 2 0 0 3]
つまり、(x) の大きさも内容も事前に知りませんでした。配列は、私が提供しているインデックスに基づいて、その場で定義する必要があります。
Pythonで、次のことを試してください:
from numpy import *
x = array([1,2])
x[4] = 3
次のエラーが発生します: IndexError: インデックスが範囲外です。回避策として、ループ内で配列をインクリメントしてから、目的の値を次のように割り当てます。
from numpy import *
x = array([1,2])
idx = 4
for i in range(size(x),idx+1):
x = append(x,0)
x[idx] = 3
print x
機能しますが、あまり便利ではなく、n 次元配列の場合は非常に面倒になる可能性があります。目標を達成するために ndarray をサブクラス化することについて考えましたが、うまくいくかどうかはわかりません。誰もがより良いアプローチを知っていますか?
早速のお返事ありがとうございます。setitemメソッドについて知りませんでした(私は Python にかなり慣れていません)。次のように ndarray クラスを単純に上書きしました。
import numpy as np
class marray(np.ndarray):
def __setitem__(self, key, value):
# Array properties
nDim = np.ndim(self)
dims = list(np.shape(self))
# Requested Index
if type(key)==int: key=key,
nDim_rq = len(key)
dims_rq = list(key)
for i in range(nDim_rq): dims_rq[i]+=1
# Provided indices match current array number of dimensions
if nDim_rq==nDim:
# Define new dimensions
newdims = []
for iDim in range(nDim):
v = max([dims[iDim],dims_rq[iDim]])
newdims.append(v)
# Resize if necessary
if newdims != dims:
self.resize(newdims,refcheck=False)
return super(marray, self).__setitem__(key, value)
そして、それは魅力のように機能します!ただし、 setitemがこの要求に従ってディメンションの数を変更できるように、上記のコードを変更する必要があります。
a = marray([0,0])
a[3,1,0] = 0
残念ながら、次のようなnumpy関数を使用しようとすると
self = np.expand_dims(self,2)
返される型は、main .marray ではなくnumpy.ndarrayです。marray が入力として提供されている場合、numpy 関数が marray を出力するように強制する方法についてのアイデアはありますか? array_wrapを使用して実行できるはずだと思いますが、正確な方法を見つけることができませんでした。どんな助けでも大歓迎です。