dtype データ型

dtype データ型

1. 学習内容



2. ストーリー

アリスのモデルの精度は、一夜にして95%から12%へと低下した。原因は、float64をint8に変換した際に、127を超えるすべての値がオーバーフローして負の数になってしまったことだった。「データ型は些細な問題ではない――間違った型を選んでしまえば、データは台無しになってしまう。」



3. 主要な概念

(1) dtype システム

NumPyのdtype(データ型)は、配列内の各要素の型を表します。すべてのndarrayには.dtype属性があります。

TEXT
np.int32    # 32-bit signed integer
np.float64  # 64-bit floating point
np.bool_    # boolean
np.str_     # unicode string
np.object_  # Python object

dtype には 2 つのフィールドがあります:

項目 意味
kind 型カテゴリ 'i'=int, 'f'=float, 'u'=uint, 'b'=bool
itemsize 要素あたりのバイト数 4(int32用)
PYTHON
import numpy as np

a = np.array([1, 2, 3])
print(a.dtype)       # int64 (on 64-bit platforms)
print(a.dtype.kind)  # 'i'
print(a.dtype.itemsize)  # 8
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。


(2) 整数型の比較

タイプ 範囲 バイト数 別名
int8 -128 ~ 127 1
int16 -32768 ~ 32767 2
int32 -2147483648 ~ 2147483647 4 intp (32ビット)
int64 -9223372036854775808 ~ 9223372036854775807 8 intp (64ビット)
uint8 0 ~ 255 1
uint16 0 ~ 65535 2
uint32 0 ~ 4294967295 4
uint64 0 ~ 18446744073709551615 8

(3) フロート型の比較

バイト数 精度 最大値 正の最小値
float16 2 約3桁 65504 5.96e-8
float32 4 約7桁 3.4e38 1.18e-38
float64 8 約15桁 1.8e308 2.23e-308
float128 16 約33桁 1.19e4932 3.36e-4932
⚠️ 注意: 多くのプラットフォームにおける float128 は、実際には80ビットの拡張精度を128ビットにパディングしたものであり、真の128ビットではありません。


(4) dtype の指定

PYTHON
import numpy as np

# By NumPy type object
a = np.array([1, 2, 3], dtype=np.float32)

# By string
b = np.array([1, 2, 3], dtype='float32')

# By single-character code
c = np.array([1, 2, 3], dtype='f4')  # float32: 'f' + 4 bytes
文字 種類
b ブール値 np.dtype('b')
i signed int np.dtype('i4') = int32
u unsigned int np.dtype('u1') = uint8
f float np.dtype('f8') = float64
c 複素数 np.dtype('c16') = complex128
S バイト列 np.dtype('S10') = 10文字の文字列
U ユニコード文字列 np.dtype('U5') = 5文字のユニコード

(5) 型変換とオーバーフロー

PYTHON
import numpy as np

# astype returns a new array with the target dtype
a = np.array([1, 2, 3], dtype=np.int32)
b = a.astype(np.float64)  # [1. 2. 3.]

# Overflow: values beyond the target range wrap around
c = np.array([100, 200, 300], dtype=np.uint8)
# [100, 200, 44]  — 300 - 256 = 44

# Float to int truncates
d = np.array([1.9, 2.5, 3.1])
print(d.astype(np.int32))  # [1 2 3]

出力: ローカルのPython環境でNumPy 2.xを実行して、ndarrayの出力を確認してください。PistonサーバーにはNumPyがプリインストールされていません。ローカルにインストールして(pip install numpy)、比較してみてください。実際の値は、NumPyのバージョンやランダムシードによって異なる場合があります。

(6) 構造化データ型

型が混在する表形式のデータについては、構造化されたデータ型を使用してください:

PYTHON
import numpy as np

# Define a structured dtype
dt = np.dtype([('name', 'U10'), ('age', 'i4'), ('salary', 'f8')])

# Create array with structured dtype
employees = np.array([
    ('Alice', 30, 75000.0),
    ('Bob', 25, 62000.0),
    ('Charlie', 35, 85000.0)
], dtype=dt)

print(employees['name'])   # ['Alice' 'Bob' 'Charlie']
print(employees['salary'].mean())  # 74000.0

出力: ローカルのPython環境でNumPy 2.xを実行して、ndarrayの出力を確認してください。PistonサーバーにはNumPyがプリインストールされていません。ローカルにインストールして(pip install numpy)、比較してみてください。実際の値は、NumPyのバージョンやランダムシードによって異なる場合があります。


(1) ▶ サンプル

TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: オーバーフローの実演 (難易度 ⭐⭐)

PYTHON
import numpy as np

# int8 range: -128 to 127
vals = np.array([100, 120, 127, 128, 130, 200], dtype=np.int8)
print("int8 values:", vals)
# [100  120  127 -128 -126  -56]

# uint8 range: 0 to 255
vals_u = np.array([200, 255, 256, 300], dtype=np.uint8)
print("uint8 values:", vals_u)
# [200 255   0  44]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(2) ▶ サンプル

TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: 構造化データ型 — 従業員レコード (難易度 ⭐⭐)

PYTHON
import numpy as np

dt = np.dtype([('name', 'U10'), ('dept', 'U15'), ('salary', 'f8'), ('years', 'i2')])

data = np.array([
    ('Alice', 'Engineering', 95000, 5),
    ('Bob', 'Marketing', 72000, 3),
    ('Charlie', 'Engineering', 110000, 8),
    ('Diana', 'Sales', 68000, 2),
], dtype=dt)

# Query by department
eng = data[data['dept'] == 'Engineering']
print("Engineering avg salary:", eng['salary'].mean())

# Sort by salary
sorted_data = np.sort(data, order='salary')
print("Top earner:", sorted_data[-1]['name'], sorted_data[-1]['salary'])
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.


4. 比較表

(1) 型変換のルール

ソース ↓ / ターゲット → int float complex 文字列
int ✅ (安全) ✅ (安全) ✅ (10進数)
float ⚠️ 切り捨て ✅ (安全) ✅ (小数)
複素数 ⚠️ 画像が失われる ⚠️ 画像が失われる ✅ (文字列)
bool ✅ (0/1) ✅ (0.0/1.0)

(2) メモリ対精度行列

データ型 100万要素 float64に対する相対値 用途
float16 2 MB 25% GPUによる学習、保存
float32 4 MB 50% ディープラーニング、ほとんどの機械学習
float64 8 MB 100% 科学計算
int8 1 MB 12.5% 画像のバイト数、フラグ
int32 4 MB 50% 汎用整数
int64 8 MB 100% 大きなインデックス、タイムスタンプ

(3) オーバーフロー時の挙動

演算 int8 uint8 float32
最大値 + 1 -128 (ループ) 0 (ループ) 無限大
最小 - 1 127 (ラップ) 255 (ラップ) -inf
0 / 0 エラー エラー NaN


5. 原理図

100%
graph TB
    A[Python object] --> B{dtype inference}
    B -->|int| C[int64]
    B -->|float| D[float64]
    B -->|mixed| E[upcast to common type]
    B -->|explicit| F[user-specified dtype]
    C --> G[ndarray with fixed dtype]
    D --> G
    E --> G
    F --> G
    G --> H[vectorized operations]
    G --> I[memory-efficient storage]
    
    style A fill:#e1f5fe
    style G fill:#c8e6c9
    style H fill:#fff9c4
    style I fill:#fff9c4

(1) ▶ サンプル:dtypeの変換とメモリ使用量(難易度 ⭐⭐)

PYTHON
import numpy as np

# Compare memory usage of different dtypes
arr_int64 = np.ones(1000000, dtype=np.int64)
arr_float32 = np.ones(1000000, dtype=np.float32)
arr_int8 = np.ones(1000000, dtype=np.int8)

print(f"int64:  {arr_int64.nbytes / 1e6:.1f} MB")
print(f"float32: {arr_float32.nbytes / 1e6:.1f} MB")
print(f"int8:   {arr_int8.nbytes / 1e6:.1f} MB")

# Convert between types
converted = arr_float32.astype(np.int32)
print(f"Converted dtype: {converted.dtype}")

出力:

TEXT
int64:  8.0 MB
float32: 4.0 MB
int8:   1.0 MB
変換後のデータ型: int32


❓ よくある質問

Q 整数のデフォルトのデータ型は何ですか?
A 64ビットプラットフォームでは int64、32ビットプラットフォームでは int32 です。NumPy はシステムのアーキテクチャに基づいて選択します。 dtype=np.int32 を指定して明示的に設定することも可能です。
Q 整数のオーバーフローが発生するとどうなりますか?
A エラーや警告は出ずに、静かにラップアラウンドします。int8(127) + 1 = -128。これはバグのよくある原因です。np.seterr(over='warn') を使ってこれを検出してください。
Q float32とfloat64は、それぞれどのような場合に使用すべきですか?
A 精度が重要な科学計算ではfloat64を使用してください。 ディープラーニング(GPUではfloat32の方が高速です)や、メモリが限られている場合はfloat32を使用してください。float32の精度は約7桁で、ほとんどの機械学習タスクには十分です。
Q 「f」と「d」の違いは何ですか?
A 「f」は float32(4バイト)、「d」は float64(8バイト)です。 これらはC言語のfloatおよびdoubleに由来する1文字のコードです。
Q 1つの配列に異なる型の要素を混在させることはできますか?
A 通常のndarrayではできません。ただし、構造化dtype(名前付き列を持つデータベースのテーブルのようなもの)や、object dtype(Pythonオブジェクトへの参照を格納するため、パフォーマンスが低下します)を使用することは可能です。

📖 まとめ



📝 練習問題

  1. 初心者 (難易度 ⭐): int8、int16、int32、int64、float32、float64 の配列を作成し、それぞれに値 1 の要素を 1000 個格納してください。それらの nbytes を出力し、メモリ使用量の違いについて説明してください。

  2. 中級(難易度 ⭐⭐):値が [0, 127, 128, 255, 256, -1] となる uint8 配列を作成してください。どの値がオーバーフローするかを観察し、その結果について説明してください。 次に、タイトル (文字列)、著者 (文字列)、出版年 (int16)、価格 (float32) というフィールドを持つ書籍カタログ用の構造化 dtype を作成してください。

  3. 上級(難易度 ⭐⭐⭐):100万個の乱数からなるfloat64配列をfloat32に変換し、その後再びfloat64に戻します。 元の配列と往復変換後の配列間の平均絶対誤差を計算する。float16についても同様に繰り返す。各型ごとの精度損失を記録する。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%