这些天,我已经从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字节的单精度浮点类型。但事实证明浮点数是8字节数据,在上面的例子中,我应该使用np.float32。
我有两个问题。
Q1 即可。 为什么浮点数是8字节而不是4字节,这可能让C / C ++程序员感到困惑?
Q2 即可。 为什么我不能使用dtype = float32。这会给我带来错误。我好像应该使用dtype = np.float32?
谢谢!
答案 0 :(得分:7)
这是因为float
是一个本机Python数据类型,它有一个底层的C-double。这是来自Python核心,而不是来自 numpy 或 scipy 。
numpy and scipy类型更具体,更符合您的期望:
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在底层C类型为float
时使用术语double
,那么答案是Python尝试比低级语言更高级别的抽象与C类似。术语float
表示浮点数的概念,而不是指定大小的特定C类型,例如float
或double
。
相比之下, numpy 允许对精确大小和内存布局进行更低级别的控制。这是其优化的关键。然而,这些优化和控制细节的能力的代价是将代码从高级抽象中移开,而你正在尝试做什么"进入"指定如何完成的细节"。