如何在BigQuery中存储Float16数组以缩减数据存储与传输成本?
BigQuery 存储压缩浮点数据方案
一、Float16 存储的替代实现
BigQuery 原生没有 FLOAT16 类型,但可以通过将 Float16 转为整数存储实现等价效果:
Float16 是 2 字节的二进制格式,可将其打包为 16 位无符号整数,存入 BigQuery 的 INT64 字段。读取时再反向转换为 Float16。
Python 示例代码:
import struct import numpy as np # 将 Float16 转为 INT64 def float16_to_int(f16_val): bytes_val = np.float16(f16_val).tobytes() return struct.unpack('<H', bytes_val)[0] # 从 INT64 转回 Float16 def int_to_float16(int_val): bytes_val = struct.pack('<H', int_val) return np.frombuffer(bytes_val, dtype=np.float16)[0]
二、序列化二进制对象推荐方案
鉴于你仅需整表读取、不做查询关联,用 BigQuery 的 BYTES 类型存储序列化后的批量数据是最优选择,推荐以下几种序列化方式:
1. NumPy 数组直接序列化
如果你的数据是批量浮点数,直接用 NumPy 序列化数组,字节开销最小、效率最高:
import numpy as np # 序列化:将浮点数数组转为 bytes(先转Float16更省空间) float_array = np.array([1.23, 4.56, 7.89], dtype=np.float16) serialized_bytes = float_array.tobytes() # 反序列化:从 bytes 恢复数组 restored_array = np.frombuffer(serialized_bytes, dtype=np.float16)
这种方式无额外序列化协议开销,适合大规模批量数据存储。
2. MessagePack 序列化
比 JSON 紧凑,跨语言兼容性好,Python 中使用 msgpack 库:
import msgpack # 序列化:支持单个或批量数据 data = [1.23, 4.56, 7.89] serialized_bytes = msgpack.packb(data, use_bin_type=True) # 反序列化 restored_data = msgpack.unpackb(serialized_bytes)
3. Pickle 序列化
Python 原生序列化方式,无需额外依赖,但需注意版本兼容性(不同 Python 版本可能无法互操作):
import pickle # 序列化 data = [1.23, 4.56, 7.89] serialized_bytes = pickle.dumps(data) # 反序列化 restored_data = pickle.loads(serialized_bytes)
注意事项
- 优先选择 NumPy 序列化(批量数据)或 MessagePack(通用场景),两者的压缩率和性能优于 Pickle。
- BigQuery 对
BYTES类型会自动进行压缩存储,可进一步降低存储成本。
内容的提问来源于stack exchange,提问作者y.selivonchyk
相关产品推荐
相关产品推荐

