python - Converting an array to a float, how to reverse the process? -
suppose start integer numpy array integers between 0 , 99, i.e.
x = np.array([[1,2,3,1],[10,5,0,2]],dtype=int)
now want represent rows in array single unique value. 1 simple way representing floating number. intuitive way
rescale = np.power(10,np.arange(0,2*x.shape[1],2)[::-1],dtype=float) codes = np.dot(x,rescale)
where exploit integers have @ 2 digits. (i'm casting rescale
float avoid exceeding maximum value of int in case entries of x
have more elements; not elegant)
this returns
array([ 1020301., 10050002.])
how can process reversed obtain x
again?
i'm thinking of converting codes
string, split string every 2nd entry. i'm not familiar these string operations, when have executed on entries of array simultaneously. problem first number has varying number of digits, trailing zeros have added in way.
maybe simpler possible using divisions or rounding, or perhaps represting rows of array in different manner. important @ least initial conversion fast , vectorized.
suggestions welcome.
first, need find correct number of columns:
number_of_cols = max(ceil(math.log(v, 100)) v in codes)
note first column 0, there no way code know existed: [[0, 1], [0, 2]] -> [1., 2.] -> [[1], [2]] or [[0, 0, 0, 1], [0, 0, 0, 2]]
. might consider.
anyways, here mockup string way:
def decode_with_string(codes): number_of_cols = max(ceil(math.log(v, 100)) v in codes) str_format = '{:0%dd}'%(2*number_of_cols) # prepare format numbers string return [[int(str_format.format(int(code))[2*i:2*i+2]) # extract wanted digits in range(number_of_cols)] # columns code in codes] # rows
but can compute numbers directly:
def decode_direct(codes): number_of_cols = max(ceil(math.log(v, 100)) v in codes) return [[floor(code/(100**index)) % 100 index in range(number_of_cols-1, -1, -1)] code in codes]
example:
>>> codes = [ 1020301., 10050002.] >>> number_of_cols = max(ceil(math.log(v, 100)) v in codes) >>> print(number_of_cols) 4 >>> print(decode_with_strings(codes)) [[1, 2, 3, 1], [10, 5, 0, 2]] >>> print(decode_direct(codes)) [[1, 2, 3, 1], [10, 5, 0, 2]]
here numpy solution:
>>> divisors = np.power(0.01, np.arange(number_of_cols-1, -1, -1)) >>> x = np.mod(np.floor(divisors*codes.reshape((codes.shape[0], 1))), 100)
finally, use float
in case of overflow of int
. first, mantissa of floating point numbers limited, don't eliminate risk of overflow. second, in python3, integer have unlimited precision.
Comments
Post a Comment