はじめに
HDFではDataを格納する際、numpyのdatatypeを指定する必要があります。numpyのデータ型とHDFのデータ型について以下の記事を参考に備忘録として記載します。
Numpyでのdatatypeについて
NumPyのデータ型dtype一覧とastypeによる変換(キャスト)に詳しい解説が書かれていますので、その中から今回用いる部分について引用します。一部加筆しています。
numpyでdtypeの書き方はいくつかあります。
各種メソッドの引数でデータ型
dtype
を指定するとき、例えばint64
型の場合は、
(1) データ型:np.int64
(2) 文字列型:'int64'
(3)型コード型:'i8'
データ型名の末尾の数字はbit
で表し、型コード末尾の数字はbyte
で表す。同じ型でも値が違うので注意。(8bit=1byte)import numpy as np a = np.array([1, 2, 3], dtype=np.int64) print(a.dtype) # int64 a = np.array([1, 2, 3], dtype='int64') print(a.dtype) # int64 a = np.array([1, 2, 3], dtype='i8') print(a.dtype) # int64
ビット精度の数値を省略して
int
やfloat
,str
のようなPythonの型で指定することもできる。この場合、等価な
dtype
に自動的に変換されるが、どのdtype
に変換されるかは環境(Python2かPython3か、32ビットか64ビットかなど)によって異なる。以下の例はPython3、64ビット環境のもの。
uint
というPythonの型はないが便宜上まとめて挙げておく。
Pythonの型 等価な dtype
の例int
int64
float
float64
str
unicode
( uint
)uint64
引数で指定する場合は
int
でも文字列'int'
でもOK。Pythonの型ではないuint
は文字列'uint'
のみ可。print(int is np.int) # True a = np.array([1, 2, 3], dtype=int) print(a.dtype) # int64 a = np.array([1, 2, 3], dtype='int') print(a.dtype) # int64
####主要なデータ型と型コード一覧(上記HPより引用)
データ型 dtype
型コード 説明 int8
i1
符号あり8ビット整数型 int16
i2
符号あり16ビット整数型 int32
i4
符号あり32ビット整数型 int64
i8
符号あり64ビット整数型 uint8
u1
符号なし8ビット整数型 uint16
u2
符号なし16ビット整数型 uint32
u4
符号なし32ビット整数型 uint64
u8
符号なし64ビット整数型 float16
f2
半精度浮動小数点型(符号部1ビット、指数部5ビット、仮数部10ビット) float32
f4
単精度浮動小数点型(符号部1ビット、指数部8ビット、仮数部23ビット) float64
f8
倍精度浮動小数点型(符号部1ビット、指数部11ビット、仮数部52ビット) float128
f16
四倍精度浮動小数点型(符号部1ビット、指数部15ビット、仮数部112ビット) complex64
c8
複素数(実部・虚部がそれぞれ float32
)complex128
c16
複素数(実部・虚部がそれぞれ float64
)complex256
c32
複素数(実部・虚部がそれぞれ float128
)bool
?
ブール型( True
orFalse
)unicode
U
Unicode文字列 object
O
Pythonオブジェクト型 Unicodeの型コードの後は文字数を指定する。
この他にも型コードとして
参考:Numpy dtype
型コード | 説明 |
---|---|
b | (signed) byte |
B | unsigned byte |
m | timedelta |
M | datetime |
S, a | zero-terminated bytes |
V | raw data (void) |
例として
dt = np.dtype('i4') # 32-bit signed integer
dt = np.dtype('f8') # 64-bit floating-point number
dt = np.dtype('c16') # 128-bit complex floating-point number
dt = np.dtype('a25') # 25-length zero-terminated bytes
dt = np.dtype('U25') # 25-character string
dt = np.dtype((np.void, 10)) # 10-byte wide data block np.dtype('V10')と同じ
dt = np.dtype(('U', 10)) # 10-character unicode string np.dtype('U10')と同じ
#####文字列について
str
やunicode
などで文字列として指定する場合のdtype
は<U1
のようになる。a_str = np.array([1, 2, 3], dtype=str) print(a_str) print(a_str.dtype) # ['1' '2' '3'] # <U1 # 1文字 a_str[0] = 'abcde' print(a_str) # ['a' '2' '3'] #1文字だけ格納。後は切り捨て。 a_str10 = np.array([1, 2, 3], dtype='U10') print(a_str10.dtype) # <U10 #10文字格納できる。 a_str10[0] = 'abcde' print(a_str10) # ['abcde' '2' '3'] #10文字以下なのですべて格納される。
先頭の
<
,>
は、それぞれリトルエンディアン、ビッグエンディアンを表している。ほとんどの場合、特に気にする必要はない。
末尾の数字は文字数を表し、この例のようにコンストラクタで
dtype
をstr
やunicode
と指定した場合、要素の中で最大の文字数となる。
それぞれの要素に対してこの文字数分のメモリしか確保されていないので、それ以上の文字数の文字列は保持できず切り捨てられる。あらかじめ十分な文字数の型を指定しておけばOK。
HDFの型と対応するNumpyの型
HDFで扱うDatatypeに対応するnumpyのdatatypeは以下のようになります。
HDF5についての書籍「Python and HDF5: Unlocking Scientific Data」 Chapter7の表からの引用一部加筆しています。
その他に参考になったのが、
意外と奥が深い、HDFの世界(Python・h5py入門)
HDF Type | Numpy Data Type | 説明 |
---|---|---|
Integer | dtype("i") | (signed) integer |
Float | dtype("f") | floating-point |
String(fixed width) | dtype("S10") or dtype("U10") | S10:10文字(ASCII文字) 、U10:ユニコード10文字 |
String(variable width) | h5py.special_dtype(vlen=str) h5py.string_dtype(encoding='utf-8') | numpyには可変長タイプはないためHDFの型指定 |
Compound | dtype([("field1":("i")),("field2":"f")]) | 上記、参考を参照 |
Enum | hypy.special_dtype(enum=("i",{"RED":0,"GREEN":1,"BLUE":2})) | 上記、参考を参照 |
Array | dtype("(2,2)f") | (2x2)でfloat型 |
Opaque | dtype("V10") | raw data (void) 10byte |
Refernece | h5py.special_dtype(ref=h5py.Reference) | HDFの型指定 |
HDF5のサンプルコード
各データタイプ別のサンプルコードは以下のHPにあります。
int型やFloat型の他に Compound Datatypes、Enumerated 、Object References、 Opaque Datatypes、Variable Length Datatypeなど普段あまり使わない型の例も乗っています。
HDF5 Python Examples by API
文字列以外のBinaryデータ(例えば、ディスクイメージやほかの数値ではないバイナリーデータ)はOpaqueTypeを使うのが良いようです。