为什么Python中的"dtype=float"是8字节而不是4字节?

4

最近,我已经从Matlab切换到了NumPy/SciPy。

今天,当我尝试加载存储在“二进制格式”中的数据时,遇到一个奇怪的问题。 音频数据以4字节单精度浮点数格式存储。 首先我尝试了以下方法。

data = np.fromfile('out.raw', dtype=float) # This is wrong
plt.plot(data)

但是它没有起作用。经过一些搜索,我尝试了以下方法,结果如预期:
data = np.fromfile('out.raw', dtype=np.float32) # This is okay.
plt.plot(data)

基于我之前对C/C++的经验,我原以为“float”是一个4字节的单精度浮点类型。但实际上,float是8字节数据,在上述情况下,我应该使用np.float32。

关于这个问题,我有两个问题。

Q1. 为什么float是8字节而不是4字节,这可能会让C/C++程序员感到困惑?

Q2. 我为什么不能使用dtype=float32呢?这给我带来了错误。好像我应该使用dtype=np.float32?

谢谢!

1个回答

12
这是因为float是一种本地Python数据类型,具有底层的C-double。这来自于Python核心而不是numpyscipyNumpyScipy类型更加具体,往往能够匹配您的预期:
bool_   Boolean (True or False) stored as a byte
int_    Default integer type (same as C long; normally either int64 or int32)
intc    Identical to C int (normally int32 or int64)
intp    Integer used for indexing (same as C ssize_t; normally either int32 or int64)
int8    Byte (-128 to 127)
int16   Integer (-32768 to 32767)
int32   Integer (-2147483648 to 2147483647)
int64   Integer (-9223372036854775808 to 9223372036854775807)
uint8   Unsigned integer (0 to 255)
uint16  Unsigned integer (0 to 65535)
uint32  Unsigned integer (0 to 4294967295)
uint64  Unsigned integer (0 to 18446744073709551615)
float_  Shorthand for float64.
float16 Half precision float: sign bit, 5 bits exponent, 10 bits mantissa
float32 Single precision float: sign bit, 8 bits exponent, 23 bits mantissa
float64 Double precision float: sign bit, 11 bits exponent, 52 bits mantissa
complex_    Shorthand for complex128.
complex64   Complex number, represented by two 32-bit floats (real and imaginary components)
complex128  Complex number, represented by two 64-bit floats (real and imaginary components)

如果你的问题是关于为什么核心Python使用术语“float”而底层C类型是“double”,那么答案是Python试图成为比C等低级语言更高级的抽象层次。术语“float”代表浮点数的概念,而不是指定大小的特定C类型,如“float”或“double”。
相比之下,“numpy”允许更低级别的控制确切的大小和内存布局。这是其优化的关键。然而,这些优化和控制细节的能力的代价是将代码从“你要做什么”的高级抽象世界转移到“如何完成它”的世界。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接