[英]Creating reference to HDF dataset in H5py using astype
從h5py文檔中 ,我看到我可以使用astype
方法為數據集投射HDF數據集作為另一種類型。 這將返回一個context Manager,它可以即時執行轉換。
但是,我想讀取存儲為uint16
的數據集,然后將其轉換為float32
類型。 之后,我想從另一個函數中提取此數據集中的各種切片作為轉換類型float32
。 文檔將使用解釋為
with dataset.astype('float32'):
castdata = dataset[:]
這將導致整個數據集被讀入並轉換為float32
,這不是我想要的。 我想引用數據集,但是將其轉換為與numpy.astype
相當的float32
。 如何創建對.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是不是一種簡潔的方式?
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
才能執行此操作。
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
已關閉,否則您將在以后遇到問題。
一般來說,我建議完全分離轉換和數據集的加載/創建,並將數據集作為函數的參數之一傳遞。
以上可以稱如下:
In [16]: get_dataset_as_float(intdata, np.min, np.max, np.mean)
Out[16]: (9.0, 87.0, 42.299999)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.