Last active
November 9, 2023 23:02
-
-
Save mullenkamp/377ff245fe56048ab68ee891f8cfbed8 to your computer and use it in GitHub Desktop.
python scale and offset calculation for shrinking data to a specific integer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import math | |
def compute_scale_and_offset(min_value: (int, float, np.number), max_value: (int, float, np.number), dtype: np.dtype): | |
""" | |
Computes the scale (slope) and offset for a dataset using a min value, max value, and the required np.dtype. | |
It leaves one value at the lower extreme to use for the nan fillvalue. | |
These are the min values set asside for the fillvalue (up to 64 bits). | |
int8: -128 | |
int16: -32768 | |
int32: -2147483648 | |
int64: -9223372036854775808 | |
Unsigned integers are allowed and a value of 0 is set asside for the fillvalue. | |
Parameters | |
---------- | |
min_value : int or float | |
The min value of the dataset. | |
max_value : int or float | |
The max value of the dataset. | |
dtype : np.dtype | |
The data type that you want to shrink the data down to. | |
Returns | |
------- | |
scale, offset as floats | |
""" | |
bits = dtype.itemsize * 8 | |
data_range = max_value - min_value | |
if bits < 64: | |
target_range = 2**bits - 2 | |
target_min = -(2**(bits - 1) - 1) | |
slope = data_range / target_range | |
else: | |
data_power = int(math.log10(data_range)) | |
target_range = 2**bits | |
target_power = int(math.log10(target_range)) | |
target_min = -10**(target_power - 1) | |
slope = 10**-(target_power - data_power) | |
# Correction if the dtype is unsigned | |
if dtype.kind == 'u': | |
target_min = 1 | |
offset = min_value - (slope*target_min) | |
return slope, offset | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment