3

h5py docsから、astypeデータセットのメソッドを使用して、HDF データセットを別のタイプとしてキャストできることがわかります。これは、オンザフライで変換を実行する contextmanager を返します。

uint16ただし、として保存されているデータセットを読み取り、それをfloat32型にキャストしたいと思います。その後、キャストタイプとして別の関数でこのデータセットからさまざまなスライスを抽出したいと思いfloat32ます。ドキュメントは、使用を次のように説明しています

with dataset.astype('float32'):
   castdata = dataset[:]

これにより、データセット全体が読み込まれて に変換されますがfloat32、これは私が望んでいるものではありません。データセットへの参照を持ちたいのですが、にfloat32相当するものとしてキャストしnumpy.astypeます。.astype('float32')オブジェクトへの参照を作成して、別の関数に渡して使用できるようにするにはどうすればよいですか?

例:

import h5py as HDF
import numpy as np
intdata = (100*np.random.random(10)).astype('uint16')

# create the HDF dataset
def get_dataset_as_float():
    hf = HDF.File('data.h5', 'w')
    d = hf.create_dataset('data', data=intdata)
    print(d.dtype)
    # uint16

    with d.astype('float32'):
    # This won't work since the context expires. Returns a uint16 dataset reference
       return d

    # this works but causes the entire dataset to be read & converted
    # with d.astype('float32'):
    #   return d[:]

さらに、データ要素にアクセスするときにのみ astype コンテキストが適用されるようです。この意味は

def use_data():
   d = get_data_as_float()
   # this is a uint16 dataset

   # try to use it as a float32
   with d.astype('float32'):
       print(np.max(d))   # --> output is uint16
       print(np.max(d[:]))   # --> output is float32, but entire data is loaded

astypeを使用する派手な方法はありませんか?

4

2 に答える 2

1

d.astype()オブジェクトを返しAstypeContextます。のソースを見ると、AstypeContext何が起こっているのかがよくわかります。

class AstypeContext(object):

    def __init__(self, dset, dtype):
        self._dset = dset
        self._dtype = numpy.dtype(dtype)

    def __enter__(self):
        self._dset._local.astype = self._dtype

    def __exit__(self, *args):
        self._dset._local.astype = None

に入ると、データセットAstypeContext._local.astype属性が新しい目的のタイプに更新され、コンテキストを終了すると元の値に戻ります。

したがって、次のように、探している動作を多かれ少なかれ取得できます。

def get_dataset_as_type(d, dtype='float32'):

    # creates a new Dataset instance that points to the same HDF5 identifier
    d_new = HDF.Dataset(d.id)

    # set the ._local.astype attribute to the desired output type
    d_new._local.astype = np.dtype(dtype)

    return d_new

から読み取るとd_new、次のfloat32代わりに numpy 配列が返されuint16ます。

d = hf.create_dataset('data', data=intdata)
d_new = get_dataset_as_type(d, dtype='float32')

print(d[:])
# array([81, 65, 33, 22, 67, 57, 94, 63, 89, 68], dtype=uint16)
print(d_new[:])
# array([ 81.,  65.,  33.,  22.,  67.,  57.,  94.,  63.,  89.,  68.], dtype=float32)

print(d.dtype, d_new.dtype)
# uint16, uint16

これは(不変のように見える)の.dtype属性を更新しないことに注意してください。d_new属性も変更したい場合dtypeは、おそらくh5py.Datasetそのためにサブクラス化する必要があります。

于 2014-08-11T13:24:14.277 に答える
0

のドキュメントは、astypeそれをすべて新しい場所に読み込むことがその目的であることを暗示しているようです。したがって、return d[:]別々の機会に多くの関数でフロートキャストを再利用する場合は、これが最も合理的です。

キャストが必要なことがわかっていて、一度だけ必要な場合は、物事を切り替えて次のようにすることができます。

def get_dataset_as_float(intdata, *funcs):
    with HDF.File('data.h5', 'w') as hf:
        d = hf.create_dataset('data', data=intdata)
        with d.astype('float32'):
            d2 = d[...]
            return tuple(f(d2) for f in funcs)

いずれにせよ、hf関数を終了する前に が閉じていることを確認する必要があります。そうしないと、後で問題が発生します。

一般に、データセットのキャストとロード/作成を完全に分離し、データセットを関数のパラメーターの 1 つとして渡すことをお勧めします。

上記は次のように呼び出すことができます。

In [16]: get_dataset_as_float(intdata, np.min, np.max, np.mean)
Out[16]: (9.0, 87.0, 42.299999)
于 2014-08-11T13:17:44.257 に答える