6.4. Dtypes¶
Kiểu phần tử của một ndarray là dtype của nó. Dtype quyết định ba điều cùng lúc: mỗi phần tử chiếm bao nhiêu byte, các byte được diễn giải như thế nào, và phạm vi giá trị mảng có thể lưu trữ. Chọn dtype phù hợp là quyết định quan trọng nhất ảnh hưởng đến mức sử dụng RAM trên camera.
6.4.1. Các dtype được hỗ trợ¶
numpy trên camera hỗ trợ một tập nhỏ các dtype:
dtype |
byte |
phạm vi |
|---|---|---|
|
1 |
0 đến 255 |
|
1 |
-128 đến 127 |
|
2 |
0 đến 65,535 |
|
2 |
-32,768 đến 32,767 |
|
4 |
IEEE 754 độ chính xác đơn |
|
1 |
|
Không có int32 hay int64, và bản build ulab của OpenMV không kích hoạt dtype complex tùy chọn.
Chọn kiểu phù hợp với phần cứng đã tạo ra dữ liệu. Mẫu ADC 8-bit dùng uint8; mẫu ADC 12-bit vừa với uint16; một điểm ảnh độ sáng từ camera thang xám vừa với uint8 -- tiết kiệm bốn lần RAM so với float mặc định.
6.4.2. Dtype mặc định¶
Dtype mặc định của mọi constructor trong Tạo mảng là float. Điều này hiếm khi phù hợp với ứng dụng khi xử lý dữ liệu cảm biến. Hãy truyền dtype= tường minh bất cứ khi nào độ rộng tự nhiên nhỏ hơn:
sensor = np.array(samples, dtype=np.uint16)
Bọc lại một mảng số nguyên mà không có đối số dtype= sẽ vừa sao chép vừa chuyển đổi sang float, vừa tốn thời gian vừa tốn RAM. Khi hiệu suất quan trọng, hãy chỉ rõ dtype.
6.4.3. Dtype của một mảng đã tồn tại¶
dtype đọc lại dtype của mảng dưới dạng mã kiểu số nguyên mà mảng lưu trữ nội bộ:
a = np.array([1, 2, 3], dtype=np.uint8)
print(a.dtype) # 66 (the integer value of ``'B'``)
Các số nguyên mã kiểu khớp với các hằng số được cung cấp trong module numpy -- numpy.uint8, numpy.int8, numpy.uint16, numpy.int16, numpy.float, numpy.bool -- do đó so sánh dtype với hằng số module là cách một tập lệnh phân nhánh dựa trên nội dung của mảng:
if a.dtype == np.uint8:
... # uint8 branch
6.4.4. Quy tắc nâng kiểu¶
Hai mảng có dtype khác nhau có thể là toán hạng của cùng một toán tử. numpy chọn kiểu kết quả theo một bảng ngắn:
trái |
phải |
kết quả |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bất kỳ |
|
|
Hàng uint16 / int16 nâng thẳng lên float vì numpy trên camera không có dtype số nguyên 32-bit.
Khi một toán tử nhị phân có một scalar Python ở một bên, scalar đó được chuyển đổi thành mảng một phần tử của dtype nhỏ nhất phù hợp: 123 trở thành mảng uint8, -1000 trở thành int16, một float Python trở thành float.
6.4.5. Tràn số nguyên theo vòng¶
Các phép toán trên hai mảng cùng dtype số nguyên giữ nguyên dtype đó, ngay cả khi kết quả bị tràn số. Phần dư bị loại bỏ lặng lẽ:
a = np.array([200, 200], dtype=np.uint8)
b = np.array([100, 100], dtype=np.uint8)
print(a + b)
Đầu ra:
array([44, 44], dtype=uint8)
Kết quả là 300 mod 256 == 44. Khi một giá trị trung gian cần phạm vi lớn hơn dtype đầu vào cho phép, hãy ép kiểu trước:
c = np.array(a, dtype=np.uint16) + b
# array([300, 300], dtype=uint16)
Quy tắc này áp dụng cho mọi toán tử số nguyên -- +, -, *, //, %, &, |, ^. Mảng float không bao giờ tràn số (chúng nâng lên vô cực thay vào đó), do đó thủ thuật ép kiểu chỉ cần thiết trong trường hợp số nguyên.