【问题标题】:Any support for reading/writing hexfloats from/to delimited files?是否支持从/向分隔文件读取/写入 hexfloats?
【发布时间】:2016-09-10 06:53:26
【问题描述】:

Python 标准库或 scipy/numpy/pandas 等是否支持从分隔文件(例如 TSV 或 CSV)读取和写入浮点数的十六进制表示(又名“hexfloats”)?

作为测试,我制作了一个 CSV 文件,其中列在十进制和十六进制浮点数之间交替,并尝试使用 pandas.read_csv 读取此文件。在生成的数据框中,包含十进制浮点数的列被正确转换为 Python 浮点数,而包含十六进制浮点数的列被保留为字符串。


编辑:澄清:我不需要帮助将 hexfloats 转换为浮点数,反之亦然。有float.fromhexfloat.hex。我正在寻找的是一个文件阅读器,它将应用合理的启发式方法来自动将 hexfloats 转换为浮点数(就像pandas.read_csv 知道将数字的十进制表示转换为数字 Python 对象一样)。

【问题讨论】:

  • 这样的文件中的分隔符是什么?
  • @hpaulj:任何不干扰数据的内容:逗号、制表符、US
  • 有没有可以使用的% 格式?例如%???%12.23`?
  • 我从未见过这样的文件格式。一个要么有一个二进制文件,如果需要,带有一个描述格式的标题,或者你需要一个分隔符,因为数字(作为字符串)的长度与它的值无关。
  • “就像 csv.reader 知道将数字的十进制表示形式转换为数字 Python 对象一样” - 你的意思是 not converting them 那么? csvreader 在 hex 浮点数和 ints 上的表现一样好 :)

标签: python csv numpy pandas scipy


【解决方案1】:
from binascii import unhexlify
from struct import unpack
hex_string="abcd33ef"
my_bytes = unhexlify(hex_string)
my_float = unpack("f",my_bytes)

我猜……也许吧?

【讨论】:

    【解决方案2】:

    我在% 格式规范中找不到任何可以为浮点数创建hex 的内容(对于整数只有%x)。因此,接受您的float.hex,我可以创建一个函数,将数组中的每个浮点数转换为十六进制字符串:

    def foo(x):
        return x.hex()
    vfoo=np.vectorize(foo)   # just for ease of applying foo to an array
    
    In [478]: x=np.arange(12.).reshape(3,4)/3
    
    In [479]: x
    Out[479]: 
    array([[ 0.        ,  0.33333333,  0.66666667,  1.        ],
           [ 1.33333333,  1.66666667,  2.        ,  2.33333333],
           [ 2.66666667,  3.        ,  3.33333333,  3.66666667]])
    
    In [480]: vfoo(x)
    Out[480]: 
    array([['0x0.0p+0', '0x1.5555555555555p-2', '0x1.5555555555555p-1',
            '0x1.0000000000000p+0'],
           ['0x1.5555555555555p+0', '0x1.aaaaaaaaaaaabp+0',
            '0x1.0000000000000p+1', '0x1.2aaaaaaaaaaabp+1'],
           ['0x1.5555555555555p+1', '0x1.8000000000000p+1',
            '0x1.aaaaaaaaaaaabp+1', '0x1.d555555555555p+1']], 
          dtype='<U20')
    

    然后我可以使用通常的savetxt 将这些字符串写入文件

    In [481]: np.savetxt('test.txt',vfoo(x), fmt='%25s',delimiter=',')
    

    看起来像:

    In [482]: cat test.txt
                     0x0.0p+0,     0x1.5555555555555p-2,     0x1.5555555555555p-1,     0x1.0000000000000p+0
         0x1.5555555555555p+0,     0x1.aaaaaaaaaaaabp+0,     0x1.0000000000000p+1,     0x1.2aaaaaaaaaaabp+1
         0x1.5555555555555p+1,     0x1.8000000000000p+1,     0x1.aaaaaaaaaaaabp+1,     0x1.d555555555555p+1
    

    loadtxt 可以处理这个问题

    In [486]: np.loadtxt('test.txt',delimiter=',')
    Out[486]: 
    array([[ 0.        ,  0.33333333,  0.66666667,  1.        ],
           [ 1.33333333,  1.66666667,  2.        ,  2.33333333],
           [ 2.66666667,  3.        ,  3.33333333,  3.66666667]])
    

    loadtxt 在看到0x 列时使用这段代码

    /usr/lib/python3/dist-packages/numpy/lib/npyio.py in floatconv(x)
        656         x.lower()
        657         if b'0x' in x:
    --> 658             return float.fromhex(asstr(x))
    

    您可能会通过研究npyio.py 文件获得其他想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-07
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2019-01-03
      • 1970-01-01
      • 2011-11-16
      相关资源
      最近更新 更多