找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2145

积分

0

好友

287

主题
发表于 2 小时前 | 查看: 4| 回复: 0

NumPy 中,数组不仅存储数据本身,还必须明确指定每个元素的数据类型。这一类型系统由 dtype(data type)对象统一管理。

Python 的动态类型不同,NumPy 数组中的元素通常具有统一的数据类型,并以固定字节数在内存中连续存储。这种设计使 NumPy 能够利用底层 C 语言实现高效的向量化计算,从而显著提升数值运算的性能。

dtype 不仅描述元素的数据类型,还包含字节大小、字节顺序以及字段结构等信息,是理解和控制数组行为的关键。

一、dtype 的基本概念

dtype 是 NumPy 中用于描述数组元素类型的核心对象。你可以通过数组的 .dtype 属性直接查看其数据类型:

ndarray.dtype

下面是一个简单的示例:

import numpy as np

a = np.array([1,2,3])
print(a.dtype)

输出:

int64

这表明该数组的元素类型为 64 位整数。

你可以在创建数组时,通过 dtype 参数显式指定类型:

np.array(data, dtype=...)

例如:

a = np.array([1,2,3], dtype=np.float64)
print(a.dtype)

输出:

float64

NumPy 的数据类型设计具有几个鲜明特点:

  • 元素类型统一:数组内所有元素共享同一数据类型。
  • 固定字节占用:每个元素占用固定大小的内存字节数。
  • 内存连续存储:数据在物理内存中是连续排列的。
  • 底层优化:运算可充分利用底层 C 语言优化甚至 SIMD 指令。

因此,dtype 的选择直接关系到数组的计算速度、内存消耗和数值精度。

NumPy 的 dtype 体系涵盖了丰富的数据类型,主要分类如下:

类型类别 示例
布尔 bool_
整数 int8, int16, int32, int64
无符号整数 uint8, uint16, uint32, uint64
浮点 float16, float32, float64(部分平台支持 float128
复数 complex64, complex128(部分平台支持 complex256
字符串 字节字符串 S
Unicode 字符串 U
对象 object_
时间 datetime64, timedelta64
结构化 structured dtype
原始数据 void

二、NumPy 的基本数值类型

NumPy 提供了一套独立于 Python 内置类型的、更精细的数值类型系统。

1. 整数类型

整数类型用于表示整型数值。

类型 字节 说明
int8 1 8 位有符号整数
int16 2 16 位有符号整数
int32 4 32 位有符号整数
int64 8 64 位有符号整数
uint8 1 无符号 8 位整数
uint16 2 无符号 16 位整数
uint32 4 无符号 32 位整数
uint64 8 无符号 64 位整数

示例:

a = np.array([1,2,3], dtype=np.int32)
print(a.dtype)

输出:int32

2. 浮点类型

浮点类型用于表示带小数的数值。

类型 字节 说明
float16 2 半精度浮点
float32 4 单精度浮点
float64 8 双精度浮点

示例:

a = np.array([1.5, 2.3, 4.8], dtype=np.float32)
print(a.dtype)

输出:float32

3. 复数类型

用于表示复数。

类型 说明
complex64 实部和虚部均为 float32
complex128 实部和虚部均为 float64

示例:

import numpy as np

a = np.array([1+2j, 3+4j], dtype=np.complex64)
print(a.dtype)

输出:complex64

4. 布尔类型

NumPy 的布尔 dtype 表示为 bool,其对应的 NumPy 标量类型为 np.bool_

示例:

import numpy as np

a = np.array([True, False, True])
print(a.dtype)

输出:bool

np.bool_ 是用于表示单个布尔值的标量类型:

import numpy as np

b = np.bool_(True)
print(b)        # True
print(type(b))  # <class 'numpy.bool_'>

当数组的 dtype 为 bool 时,其内部每个元素实际上都是 np.bool_ 类型的标量对象。

import numpy as np

a = np.array([True, False, True])
print(type(a[0]))    # <class 'numpy.bool_'>

三、dtype 类型代码

除了完整的类型名称,NumPy 还支持一种更简短的表示方式——类型代码。它通常由 类型字母 + 字节数 组成。

常见类型代码对照表:

类型代码 等价类型 说明
i1 int8 8 位有符号整数
i2 int16 16 位有符号整数
i4 int32 32 位有符号整数
i8 int64 64 位有符号整数
u1 uint8 无符号 8 位整数
u2 uint16 无符号 16 位整数
u4 uint32 无符号 32 位整数
u8 uint64 无符号 64 位整数
f4 float32 单精度浮点
f8 float64 双精度浮点
c8 complex64 复数(两个 float32
c16 complex128 复数(两个 float64

示例:

import numpy as np

a = np.array([1,2,3], dtype="i4")
print(a.dtype)  # int32

类型代码中常见的类型字母含义:

字母 含义
b 布尔
i 有符号整数
u 无符号整数
f 浮点数
c 复数
S 字节字符串
U Unicode 字符串
O Python 对象
M datetime64
m timedelta64
V void(原始数据)

类型代码常用于以下场景:

  1. 快速指定 dtypedtype="f8"
  2. 定义结构化数组dtype=[("age","i4"),("score","f4")]
  3. 二进制数据解析np.fromfile("data.bin", dtype="i2")
  4. dtype 字符串表示:例如 dtype('<f8'),其中 < 表示小端序(little-endian),f8 表示 8 字节浮点数。

四、字节序

NumPy 的 dtype 还可以描述数据的字节顺序

符号 含义
< little-endian(小端序)
> big-endian(大端序)
= 本机字节序

示例:

import numpy as np

dt = np.dtype("<f8")  # little-endian float64
print(dt)

NumPy dtype 的完整字符串格式是:字节序 + 类型 + 大小
例如:

<i4   little-endian int32
>i4   big-endian int32
<f8   little-endian float64
  • 小端序:低位字节存放在内存的低地址处。
  • 大端序:高位字节存放在内存的低地址处。

理解字节序对于二进制文件读写和跨平台数据交换尤为重要。

五、其它数据类型

1. 字符串类型

NumPy 支持固定长度的字符串。

类型 说明
S 字节字符串
U Unicode 字符串

示例:

import numpy as np

a = np.array(["apple", "banana"], dtype="U10")
print(a.dtype)

输出:<U10
说明:U10 表示最多 10 个 Unicode 字符,< 是字节序标记。

2. 时间类型

NumPy 提供了专门的时间数据类型。

  • datetime64:用于表示具体的日期和时间。

    import numpy as np
    
    a = np.array(["2026-01-01", "2026-01-02"], dtype="datetime64[D]")  # [D] 表示单位为 day
    print(a)

    输出:['2026-01-01' '2026-01-02']

  • timedelta64:用于表示时间间隔。

    import numpy as np
    
    a = np.array([1,2,3], dtype="timedelta64[D]")
    print(a)

    输出:[1 2 3],数值代表以天为单位的时间间隔数量。

常用时间单位:

单位 含义
Y
M
D
h 小时
m 分钟
s
ms 毫秒

3. Python 对象类型

NumPy 也可以存储任意 Python 对象,此时 dtype 为 object

import numpy as np

# 创建 object 类型数组
a = np.array([1, "hello", [1,2,3]], dtype=object)
print(a)
# 查看数组元素的类型
print(type(a[1]))

输出示例:

[1 'hello' list([1, 2, 3])]
<class 'numpy.object_'>

numpy.object_ 是用于封装任意 Python 对象的标量类型。也可以直接创建:

import numpy as np

x = np.object_("hello")
print(x)        # hello
print(type(x))  # <class 'numpy.object_'>

需要注意的是,dtype 为 object 的数组不再是高效的数值数组:

  • 每个元素存储的是 Python 对象引用。
  • 计算速度远慢于普通数值数组。
  • 通常只用于存放异构数据等特殊场景。

4. 结构化数据类型

NumPy 允许数组元素包含多个字段,类似于 C 语言中的结构体,这极大地增强了其处理表格型数据的能力。

import numpy as np

dtype = np.dtype([
    ("name", "U10"),
    ("age", "i4"),
    ("score", "f4")
])

data = np.array([
    ("艾婉婷", 18, 88.5),
    ("岳露珊", 19, 92.0)
], dtype=dtype)

print(data)

输出:

[('艾婉婷', 18, 88.5) ('岳露珊', 19, 92. )]

你可以通过字段名访问整列数据:

print(data["age"])

输出:[18 19]

结构化数组是处理带有混合类型字段的记录数据的利器。

六、类型转换

使用 astype() 方法可以进行数组数据类型的转换。注意,此操作会创建一个新的数组副本。

ndarray.astype(dtype)

示例:

import numpy as np

a = np.array([1,2,3], dtype=np.int32)
b = a.astype(np.float64)

print(b.dtype)

输出:float64

小结

dtype 是 NumPy 数组的灵魂,它精确定义了数组元素的数据类型、内存布局和存储结构。从基本的整数、浮点数,到复杂的复数和结构化类型,NumPy 提供了一套完备的数据类型系统来满足科学计算的各种需求。掌握如何在创建数组时指定 dtype,以及如何使用 astype() 进行转换,是高效利用 NumPy 进行数据处理和数值计算的基础。希望这篇指南能帮助你在 云栈社区 的编程之路上更进一步,更深入地理解数据背后的细节。




上一篇:AI编程助手提效:pua项目在Claude Code、Cursor中的实战与应用
下一篇:独立游戏开发者的高效路径:一人全职带娃,用一年做出肉鸽策略游戏《天选花园》
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-15 20:17 , Processed in 0.693568 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表