2

私は次の形式のnumpy構造化配列を持っています:

x = np.array([(1,2,3)]*2, [('t', np.int16), ('x', np.int8), ('y', np.int8)])

't'ここで、またはのいずれかと'x'連携するビューをこの配列に生成したいと思います'y'。通常の構文では、コピーが作成されます。

v_copy = x[['t', 'y']]
v_copy
#array([(1, 3), (1, 3)], 
#     dtype=[('t', '<i2'), ('y', '|i1')])

v_copy.base is None
#True

2つのフィールドを選択することは「ファンシーインデックス」であり、その時点でnumpyはあきらめてコピーを作成するため、これは予想外のことではありません。私の実際の記録は大きいので、絶対にコピーを避けたいです。

numpyのストライドメモリモデル内で必要な要素にアクセスできないというのは、まったく真実ではありません。メモリ内の個々のバイトを見る:

x.view(np.int8)
#array([1, 0, 2, 3, 1, 0, 2, 3], dtype=int8)

必要な歩みを理解することができます:

v = np.recarray((2,2), [('b', np.int8)], buf=x, strides=(4,3))
v
#rec.array([[(1,), (3,)],
#    [(1,), (3,)]], 
#    dtype=[('b', '|i1')])
v.base is x
#True

明らかにv、コピーを作成せずにメモリ内の正しい場所を指しています。残念ながら、numpyでは、これらのメモリ位置を元のデータ型として再解釈することはできません。

v_view = v.view([('t', np.int16), ('y', np.int8)])
#ValueError: new type not compatible with array.

numpyをだましてこのキャストを実行させ、コピーを作成せずにとv_view同等の配列を作成する方法はありますか?で行われているv_copyように、おそらく直接作業していますか?v.__array_interface__np.lib.stride_tricks.as_strided()

4

2 に答える 2

1

あなたはそのように適切なdtypeを構築することができます

dt2 = np.dtype(dict(names=('t', 'x'), formats=(np.int16, np.int8), offsets=(0, 2)))

そしてします

y = np.recarray(x.shape, buf=x, strides=x.strides, dtype=dt2)

将来のNumpyバージョン(> 1.6)では、次のこともできます

dt2 = np.dtype(dict(names=('t', 'x'), formats=(np.int16, np.int8), offsets=(0, 2), itemsize=4))
y = x.view(dt2)
于 2012-08-03T09:26:47.167 に答える
0

これはnumpy1.6.xで機能し、recarray:の作成を回避します。

dt2 = {'t': (np.int16, 0), 'y': (np.int8, 3)}
v_view = np.ndarray(x.shape, dtype=dt2, buffer=x, strides=x.strides)
v_view
#array([(1, 3), (1, 3)], 
#    dtype=[('t', '<i2'), ('', '|V1'), ('y', '|i1')])
v_view.base is x
#True

これをクラスのオーバーロードでラップすることができますnp.ndarray

class arrayview(np.ndarray):
    def __new__(subtype, x, fields):
        dtype = {f: x.dtype.fields[f] for f in fields}
        return np.ndarray.__new__(subtype, x.shape, dtype,
                                  buffer=x, strides=x.strides)

v_view = arrayview(x, ('t', 'y'))
v_view
#arrayview([(1, 3), (1, 3)], 
#    dtype=[('t', '<i2'), ('', '|V1'), ('y', '|i1')])
v_view.base is x
#True
于 2012-08-05T10:00:21.013 に答える