weatherforecast1024's picture
Upload folder using huggingface_hub
d2f661a verified
Raw
History Blame Contribute Delete
3.98 kB
from numba import njit, prange
import numpy as np
from scipy.signal import convolve
def log_scale_with_zero(range, n=65536, dtype=np.float32):
scale = np.linspace(np.log10(range[0]), np.log10(range[1]), n-1)
scale = np.hstack((0, 10**scale)).astype(dtype)
return scale
def log_quantize_with_zero(x, range, n=65536, dtype=np.uint16):
scale = log_scale_with_zero(range, n=n, dtype=x.dtype)
y = np.empty_like(x, dtype=dtype)
log_quant_with_zeros(x, y, np.log10(scale[1:]))
return (y, scale)
# optimized helper function for the above
@njit(parallel=True)
def log_quant_with_zeros(x, y, scale):
x = x.ravel()
y = y.ravel()
min_val = 10**scale[0]
for i in prange(x.shape[0]):
# map small values to 0
if x[i] < min_val:
y[i] = 0
continue
lx = np.log10(x[i])
if lx >= scale[-1]:
# map too big values to max of scale
y[i] = len(scale)
else:
# binary search for the rest
k0 = 0
k1 = len(scale)
while k1-k0 > 1:
km = k0 + (k1-k0)//2
if lx < scale[km]:
k1 = km
else:
k0 = km
if k0 == len(scale)-1:
q = k0
elif k0 == 0:
q = 0
else:
d0 = abs(lx-scale[k0])
d1 = abs(lx-scale[k1])
if d0 < d1:
q = k0
else:
q = k1
y[i] = q+1 # add 1 to leave space for zero
@njit(parallel=True)
def average_pool(x, factor=2, missing=65535):
y = np.empty((x.shape[0]//factor, x.shape[1]//factor), dtype=x.dtype)
N = factor**2
N_thresh = N//2
for iy in prange(y.shape[0]):
ix0 = iy * factor
ix1 = ix0 + factor
for jy in range(y.shape[1]):
jx0 = jy * factor
jx1 = jx0 + factor
v = float(0.0)
num_valid = 0
for ix in range(ix0, ix1):
for jx in range(jx0, jx1):
if x[ix,jx] != missing:
v += x[ix,jx]
num_valid += 1
if num_valid >= N_thresh:
y[iy,jy] = v/num_valid
else:
y[iy,jy] = missing
return y
@njit(parallel=True)
def mode_pool(x, num_values=256, factor=2):
y = np.empty((x.shape[0]//factor, x.shape[1]//factor), dtype=x.dtype)
for iy in prange(y.shape[0]):
v = np.empty(num_values, dtype=np.int64)
ix0 = iy * factor
ix1 = ix0 + factor
for jy in range(y.shape[1]):
jx0 = jy * factor
jx1 = jx0 + factor
v[:] = 0
for ix in range(ix0, ix1):
for jx in range(jx0, jx1):
v[x[ix,jx]] += 1
y[iy,jy] = v.argmax()
return y
def fill_holes(missing=65535, rad=1):
def fill(x):
# identify mask of points to fill
o = np.ones((2*rad+1,2*rad+1), dtype=np.uint16)
n = np.prod(o.shape)
valid = (x != missing)
num_valid_neighbors = convolve(valid, o, mode='same', method='direct')
mask = ~valid & (num_valid_neighbors > 0)
# compute mean of valid points around each fillable point
fx = x.copy()
fx[~valid] = 0
mx = convolve(fx, o.astype(np.float64), mode='same', method='direct')
mx = mx[mask] / num_valid_neighbors[mask]
if np.issubdtype(x.dtype, np.integer):
mx = mx.round().astype(x.dtype)
# fill holes with mean
fx = x.copy()
fx[mask] = mx
return fx
return fill