Проверьте, представляет ли байтовая строка float или int - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть некоторые byte strings, и я не знаю, являются ли они целыми числами или числами с плавающей запятой.

Позволяет создать некоторые примеры данных:

import numpy as np
arr_int =   np.array([17,    int(1e10),  34567])
arr_float = np.array([17.17, 1e10/np.pi, 34567.8])
arr_int_b = arr_int.tobytes()
# b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0bT\x02\x00\x00\x00\x07\x87\x00\x00\x00\x00\x00\x00'
arr_float_b = arr_float.tobytes()
# b'\xecQ\xb8\x1e\x85+1@"\xd0\xba}G\xb7\xe7A\xd9\xce\xf7S\xe3\xa5\x0b@'

Если я читаю их с numpy.frombuffer(.., dtype=float/int) и использовать неправильное dtype Я получаю либо очень большие значения (float-> int), либо действительно маленькие значения (int-> float).

arr_float2int = np.frombuffer(arr_float_b, dtype=int)
# array([4625526143032250860, 4748965849765433378, 4674983775839033754])
arr_int2float = np.frombuffer(arr_int_b, dtype=float)
# array([8.39911598e-323, 4.94065646e-314, 1.70783672e-319])

Сейчас я использую такую ​​проверку, чтобы убедиться, что получаю правильные результаты:

arr = np.frombuffer(arr_b, dtype=int)
if np.mean(arr) > 1e12:
    arr = np.frombuffer(arr_b, dtype=float)

Это работает в моем случае, потому что я знаю, что у меня не будет целые числа со значениями больше 10000. И я также знаю, что у меня не будет float с действительно маленькими значениями. Мне любопытно, если есть более общий (и безопасный) способ проверить это.

Но я предполагаю, что если разрешены все целые числа и все числа с плавающей запятой, невозможно отличить от строки байтов:

np.frombuffer(np.array([1e-320]).tobytes(), dtype=int)
# array([2024])
np.frombuffer(np.array([int(46e17)]).tobytes(), dtype=float)
# array([0.35129566])
...