Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python NumPy: เปลี่ยน Data Type ของ Array (dtype, astype)

NumPy Array มี dtype (Data Type) ที่กำหนดขนาดและรูปแบบของข้อมูลในหน่วยความจำ การเปลี่ยน dtype สำคัญสำหรับ Memory Efficiency, Numerical Precision และ Compatibility กับ Libraries อื่นๆ

ตรวจสอบ Data Type ปัจจุบัน: array.dtype

import numpy as np

# สร้าง Array
a = np.array([21.23, 13.1, 52.1, 8, 255])
print(f"Array: {a}")
print(f"dtype: {a.dtype}")       # float64
print(f"itemsize: {a.itemsize} bytes")  # 8 bytes per element

NumPy Data Types (Common)

TypeAliasSizeRange / Description
boolbool_1 byteTrue/False
int8int81 byte-128 to 127
int16int162 bytes-32,768 to 32,767
int32int32, int4 bytes-2B to 2B
int64int64, long8 bytes-9E18 to 9E18
uint8uint81 byte0 to 255 (Image Processing)
float16float16, half2 bytesHalf Precision
float32float32, single4 bytesSingle Precision (Deep Learning)
float64float64, double8 bytesDouble Precision (Default)
complex64complex648 bytesComplex (2x float32)
complex128complex12816 bytesComplex (2x float64)
objectobjectPointerPython Objects (Flexible but Slow)
string_strVariableFixed-length String
unicode_UVariableUnicode String

เปลี่ยน Data Type: array.astype()

คืนค่า New Array Copy (ไม่แก้ไข Array เดิม)

import numpy as np

a = np.array([21.23, 13.1, 52.1, 8, 255])
print(f"Original: {a}, dtype: {a.dtype}")

# 1. Float -> Integer (Truncates Decimal!)
a_int = a.astype('int32')  # หรือ np.int32, 'i4'
print(f"int32:    {a_int}, dtype: {a_int.dtype}")  # [21 13 52 8 255]

# 2. Float -> String
a_str = a.astype('str')  # หรือ 'U' (Unicode), ' Complex
a_cmplx = a.astype('complex64')
print(f"complex64: {a_cmplx}, dtype: {a_cmplx.dtype}")  # [21.23+0.j 13.1+0.j ...]

# 4. Integer -> Float
b = np.array([1, 2, 3], dtype=np.int32)
b_float = b.astype(np.float64)
print(f"int32 -> float64: {b_float}, dtype: {b_float.dtype}")

# 5. Boolean Conversion
c = np.array([0, 1, -5, 0, 10])
c_bool = c.astype(bool)
print(f"bool: {c_bool}")  # [False True True False True]

การระบุ dtype แบบต่างๆ

import numpy as np

arr = np.array([1, 2, 3])

# String Specifiers
print(arr.astype('int32').dtype)    # 'int32' or 'i4'
print(arr.astype('float64').dtype)  # 'float64' or 'f8'
print(arr.astype('complex').dtype)  # 'complex128'
print(arr.astype('bool').dtype)     # 'bool'
print(arr.astype('U10').dtype)      # Unicode String length 10

# NumPy Type Objects
print(arr.astype(np.int16).dtype)   # np.int16
print(arr.astype(np.float32).dtype) # np.float32

# Structured Types
dt = np.dtype([('name', 'U10'), ('age', 'i4'), ('score', 'f4')])
structured = np.array([('Alice', 25, 95.5), ('Bob', 30, 87.0)], dtype=dt)
print(structured['name'])

ข้อควรระวัง: Data Loss และ Overflow

import numpy as np

# 1. Float -> Int: Truncation (ไม่ได้ Round!)
arr = np.array([1.9, 2.5, -3.7])
print(arr.astype(int))  # [1 2 -3]  (Truncates toward zero)

# ใช้ Round ก่อนถ้าต้องการ Round
print(np.round(arr).astype(int))  # [2 2 -4]

# 2. Overflow: Large Number -> Small Type
large = np.array([300, 400], dtype=np.int32)
print(large.astype(np.int8))  # [44, 144]  (Overflow! 300 % 256 = 44)

# 3. Unsigned <- Negative
neg = np.array([-1, -5], dtype=np.int32)
print(neg.astype(np.uint8))  # [251, 251]  (Two's Complement)

Memory Efficiency Example

import numpy as np
import sys

# 1 ล้านตัวเลข
size = 1_000_000

# float64 (Default) - 8 MB
arr_f64 = np.random.rand(size)
print(f"float64: {arr_f64.nbytes / 1e6:.1f} MB")

# float32 - 4 MB (ครึ่งหนึ่ง!)
arr_f32 = arr_f64.astype(np.float32)
print(f"float32: {arr_f32.nbytes / 1e6:.1f} MB")

# int8 - 1 MB (ถ้าข้อมูลอยู่ในช่วง -128 ถึง 127)
arr_i8 = (np.random.rand(size) * 200 - 100).astype(np.int8)
print(f"int8: {arr_i8.nbytes / 1e6:.1f} MB")

สรุป

  • array.dtype: ดู Data Type ปัจจุบัน
  • array.astype(new_dtype): สร้าง Array ใหม่ด้วย dtype ใหม่ (Copy)
  • ระวัง Truncation (Float->Int), Overflow (Large->Small Type), Sign Change (Signed<->Unsigned)
  • ใช้ dtype ที่เล็กที่สุดที่รองรับข้อมูลได้ เพื่อประหยัด Memory และเพิ่ม Speed (Cache Efficiency)
  • Deep Learning: ใช้ float32 (มาตรฐาน), float16 (Mixed Precision)
  • Image Processing: ใช้ uint8 (0-255)