Skip to content

Instantly share code, notes, and snippets.

@mullenkamp
Last active November 9, 2023 23:02
Show Gist options
  • Save mullenkamp/377ff245fe56048ab68ee891f8cfbed8 to your computer and use it in GitHub Desktop.
Save mullenkamp/377ff245fe56048ab68ee891f8cfbed8 to your computer and use it in GitHub Desktop.
python scale and offset calculation for shrinking data to a specific integer
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