You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按位宽/特定int dtype一次性配置Numpy全局打印格式?

按位宽正确格式化Numpy混合位宽二进制数据的一次性解决方案

问题背景

处理大量混合位宽的二进制数据时,希望在单个打印/日志语句中按数据自身位宽正确格式化输出,避免每次打印前反复调用np.set_printoptions或自定义格式化函数。

原尝试及问题

以下示例中,设置的uint32/uint16格式化器未生效,所有整数类型均 fallback 到int格式化规则,导致16位数据被按32位格式化:

import numpy as np

numbers_32_bit = np.array((0x1000_0000, 0x2000_0000, 0x3000_0000, 0x4000_0000), dtype=np.uint32)
numbers_16_bit = np.array((0x5000, 0x6000, 0x7000, 0x8000), dtype=np.uint16)

np_formatter = {
    # 无报错但无效果,符合Numpy文档说明
    "uint32": lambda x: f"{x:08X}",
    "uint16": lambda x: f"{x:04X}",
    # 作用于所有整数类型
    "int": lambda x: f"0x{x:08X}"
}

np.set_printoptions(formatter=np_formatter)
print(f"32 bits: {numbers_32_bit}, 16 bits: {numbers_16_bit}")

输出结果:

32 bits: [0x10000000 0x20000000 0x30000000 0x40000000], 16 bits: [0x00005000 0x00006000 0x00007000 0x00008000]

逐语句调整格式化器的方法虽然有效,但在大量打印场景下效率低下:

def format_bitwidths(n8=0, n16=0, n32=0, n64=0):
    np.set_printoptions(formatter={"int": lambda x: f"0x{x:02X}"})
    s8 = f"{n8}"
    np.set_printoptions(formatter={"int": lambda x: f"0x{x:04X}"})
    s16 = f"{n16}"
    np.set_printoptions(formatter={"int": lambda x: f"0x{x:08X}"})
    s32 = f"{n32}"
    np.set_printoptions(formatter={"int": lambda x: f"0x{x:016X}"})
    s64 = f"{n64}"
    return s8, s16, s32, s64

_, str_16_bits, str_32_bits, _ = format_bitwidths(n16=numbers_16_bit, n32=numbers_32_bit)
print(f"32 bits: {str_32_bits}, 16 bits: {str_16_bits}")

输出结果:

32 bits: [0x10000000 0x20000000 0x30000000 0x40000000], 16 bits: [0x5000 0x6000 0x7000 0x8000]

一次性解决方案

通过自定义动态格式化函数,利用数组的dtype属性判断位宽,只需设置一次全局格式化器即可永久生效:

import numpy as np

def dynamic_formatter(x):
    # 获取元素的dtype名称
    dtype_name = x.dtype.name
    # 根据不同位宽的无符号整数设置格式化规则
    if dtype_name == 'uint8':
        return f"0x{x:02X}"
    elif dtype_name == 'uint16':
        return f"0x{x:04X}"
    elif dtype_name == 'uint32':
        return f"0x{x:08X}"
    elif dtype_name == 'uint64':
        return f"0x{x:016X}"
    # 处理有符号整数类型
    elif dtype_name.startswith('int'):
        bit_width = int(dtype_name.split('int')[-1])
        return f"0x{x:0{bit_width//4}X}"
    # 非整数类型默认返回字符串
    else:
        return str(x)

# 一次性设置全局打印选项
np.set_printoptions(formatter={"int": dynamic_formatter})

# 测试多种位宽数据
numbers_8_bit = np.array((0x12, 0x34, 0x56, 0x78), dtype=np.uint8)
numbers_16_bit = np.array((0x5000, 0x6000, 0x7000, 0x8000), dtype=np.uint16)
numbers_32_bit = np.array((0x1000_0000, 0x2000_0000, 0x3000_0000, 0x4000_0000), dtype=np.uint32)
numbers_64_bit = np.array((0x1000000000000000, 0x2000000000000000), dtype=np.uint64)

# 单语句打印所有混合位宽数据
print(f"8 bits: {numbers_8_bit}, 16 bits: {numbers_16_bit}, 32 bits: {numbers_32_bit}, 64 bits: {numbers_64_bit}")

输出结果:

8 bits: [0x12 0x34 0x56 0x78], 16 bits: [0x5000 0x6000 0x7000 0x8000], 32 bits: [0x10000000 0x20000000 0x30000000 0x40000000], 64 bits: [0x1000000000000000 0x2000000000000000]

方案原理

Numpy的打印格式化器中,"int"键会匹配所有整数类型(包括无符号)。自定义的dynamic_formatter函数通过读取数组元素的dtype,动态生成对应位宽的格式化字符串,实现了不同位宽数据自动应用正确的格式化规则,且只需设置一次即可在整个脚本中生效。

内容的提问来源于stack exchange,提问作者rici1241

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:16:06