Skip to content

NumPy 属性与 dtype

本章目标

  1. 掌握数组结构属性 shapendimsize 及其关系
  2. 掌握类型与内存属性 dtypeitemsizenbytes
  3. 会用 np.iinfo / np.finfo 查询整数与浮点类型的取值范围和精度
  4. 掌握 astype 的类型转换用法
  5. 掌握布尔数组与条件筛选的基础模式

重点方法与概念速览

名称类型作用
arr.shape属性各维度长度组成的元组
arr.ndim属性维度数量,等于 len(shape)
arr.size属性元素总数,等于各维度长度乘积
arr.dtype属性元素数据类型对象
arr.itemsize属性每个元素占用字节数
arr.nbytes属性数组总字节数,等于 size × itemsize
arr.astype(...)方法返回类型转换后的新数组
np.iinfo(...)函数查询整数类型的取值范围和位数
np.finfo(...)函数查询浮点类型的精度参数和范围
arr > x 等比较运算符表达式生成布尔数组
arr[mask]表达式用布尔数组进行索引筛选

1. 数组结构属性

arr.shape

作用

返回各维度长度组成的元组。例如 (3, 4) 表示 3 行 4 列,一维向量为 (n, )

返回内容

类型含义
tuple[int, ...]各维度长度,ndim 等于元组长度

arr.ndim

作用

返回数组的维度数量(轴数),等于 len(arr.shape)。标量为 0,向量为 1,矩阵为 2

返回内容

类型含义
int维度数量

arr.size

作用

返回数组中所有元素的总数,等于各维度长度的乘积:shape[i]

返回内容

类型含义
int元素总数

示例代码

python
import numpy as np

arr = np.random.random((3, 4))
print(arr)
print(f"shape: {arr.shape}")
print(f"ndim: {arr.ndim}")
print(f"size: {arr.size}")
print(f"行数: {arr.shape[0]}, 列数: {arr.shape[1]}")

输出

text
[[0.86395484 0.55333229 0.49186088 0.65651355]
 [0.65818868 0.01198379 0.0954384  0.54282681]
 [0.3904872  0.28345003 0.64304407 0.45011224]]
shape: (3, 4)
ndim: 2
size: 12
行数: 3, 列数: 4

理解重点

  • ndim == len(shape),始终成立
  • size == shape[0] × shape[1] × ...,始终成立
  • shape 是后续索引、广播、变形的基础——拿到数组先看 shape

2. 内存与数据类型属性

arr.dtype

作用

返回数组元素的数据类型对象,决定了每个元素的存储方式和取值范围。

返回内容

类型含义
numpy.dtype数据类型描述对象,如 float64int32

arr.itemsize

作用

返回每个元素占用的字节数。float64 为 8 字节,float32 为 4 字节。

返回内容

类型含义
int单个元素的字节数

arr.nbytes

作用

返回数组占用的总字节数,计算公式:nbytes=size×itemsize

返回内容

类型含义
int数组总字节数

示例代码

python
import numpy as np

arr = np.random.random((3, 4))
print(f"dtype: {arr.dtype}")
print(f"itemsize: {arr.itemsize}")
print(f"nbytes: {arr.nbytes}")
print(f"验证 size × itemsize: {arr.size * arr.itemsize}")

输出

text
dtype: float64
itemsize: 8
nbytes: 96
验证 size × itemsize: 96

理解重点

  • float64 每元素 8 字节,float32 每元素 4 字节——内存翻倍
  • 大数组先估算内存:arr.nbytes / 1024**2 得 MB 数
  • 内存紧张时可考虑 float32 替换 float64

3. 常见数据类型

常见 dtype 一览

dtype 名称类别每元素字节数典型取值范围 / 精度
bool_布尔1True / False
int8有符号整数1[128,127]
int16有符号整数2[32768,32767]
int32有符号整数4[231,2311]
int64有符号整数8[263,2631]
uint8无符号整数1[0,255]
float16半精度浮点2约 3 位有效数字
float32单精度浮点4约 6~7 位有效数字
float64双精度浮点8约 15 位有效数字
complex64复数8实部 + 虚部各 float32
complex128复数16实部 + 虚部各 float64

np.iinfo

作用

查询整数类型的元信息:最小值、最大值、位数。返回一个包含这些属性值的对象。

重点方法

python
np.iinfo(int_type)

参数

参数名类型说明示例取值
int_typedtype任意 NumPy 整数 dtype 或整数数组的类型np.int32

返回内容

属性类型含义
.minint该类型可表示的最小值
.maxint该类型可表示的最大值
.bitsint占用的二进制位数
.dtypedtype对应的 dtype 对象

示例代码

python
import numpy as np

for dtype in [np.int8, np.int16, np.int32, np.int64]:
    info = np.iinfo(dtype)
    print(f"{dtype.__name__}: [{info.min}, {info.max}]")

输出

text
int8: [-128, 127]
int16: [-32768, 32767]
int32: [-2147483648, 2147483647]
int64: [-9223372036854775808, 9223372036854775807]

np.finfo

作用

查询浮点类型的精度参数:机器精度、有效位数、最小/最大值等。

重点方法

python
np.finfo(dtype)

参数

参数名类型说明示例取值
dtypedtype任意 NumPy 浮点 dtype 或浮点数组的类型np.float32

返回内容

属性类型含义
.epsfloat机器精度,使 1+ε>1 的最小正数
.minfloat该类型可表示的最小值(最负)
.maxfloat该类型可表示的最大值(最正)
.precisionint十进制有效位数
.bitsint占用位数
.resolutionfloat该类型的近似分辨率

示例代码

python
import numpy as np

for dtype in [np.float16, np.float32, np.float64]:
    info = np.finfo(dtype)
    print(f"{dtype.__name__}: 精度 {info.precision} 位, eps={info.eps}")

输出

text
float16: 精度 3 位, eps=0.000977
float32: 精度 6 位, eps=1.1920929e-07
float64: 精度 15 位, eps=2.220446049250313e-16

4. 类型转换

ndarray.astype

作用

将数组元素转换为目标 dtype,返回新数组。浮点转整数是截断(向零取整),不是四舍五入。

重点方法

python
arr.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)

参数

参数名类型说明示例取值
dtypedtypestr目标数据类型np.int32str
orderstr内存布局:'K' 保持原样 / 'C' 行优先 / 'F' 列优先 / 'A' 任意,默认为 'K''C'
castingstr类型转换策略:'no' / 'equiv' / 'safe' / 'same_kind' / 'unsafe',从严格到宽松,默认为 'unsafe''safe'
subokboolTrue 保留子类类型,默认为 TrueFalse
copyboolTrue 总是复制,默认为 TrueFalse

示例代码

python
import numpy as np

arrFloat = np.array([1.5, 2.7, 3.2, 4.8])
arrInt = arrFloat.astype(np.int32)
arrStr = arrFloat.astype(str)

print(f"原数组: {arrFloat}, dtype={arrFloat.dtype}")
print(f"转 int32: {arrInt}, dtype={arrInt.dtype}")
print(f"转 str: {arrStr}, dtype={arrStr.dtype}")

输出

text
原数组: [1.5 2.7 3.2 4.8], dtype=float64
转 int32: [1 2 3 4], dtype=int32
转 str: ['1.5' '2.7' '3.2' '4.8'], dtype=<U32

理解重点

  • 浮点转整数是截断(向零取整),1.91-1.9-1——如需四舍五入先用 np.round
  • astype 返回新数组,不修改原数组——每次调用都有拷贝开销
  • 大数组频繁类型转换是性能瓶颈,应在创建时指定正确的 dtype

5. 布尔数组与条件筛选

作用

通过比较运算符(><==!= 等)生成与原数组同形状的布尔数组,再用布尔数组作为索引完成条件过滤。这是 NumPy 最常用、最高效的筛选模式。

运算符一览

运算符含义返回
>逐元素大于布尔数组
<逐元素小于布尔数组
>=逐元素大于等于布尔数组
<=逐元素小于等于布尔数组
==逐元素等于布尔数组
!=逐元素不等布尔数组

组合条件使用 &(与)、|(或)、~(非),不能使用 Python 的 and/or/not,每个条件必须加括号。

示例代码

python
import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
mask = arr > 5

print(f"原数组: {arr}")
print(f"mask (arr > 5): {mask}")
print(f"mask.dtype: {mask.dtype}")
print(f"筛选结果 arr[mask]: {arr[mask]}")
print(f"大于 5 的元素个数: {mask.sum()}")

输出

text
原数组: [ 1  2  3  4  5  6  7  8  9 10]
mask (arr > 5): [False False False False False  True  True  True  True  True]
mask.dtype: bool
筛选结果 arr[mask]: [ 6  7  8  9 10]
大于 5 的元素个数: 5

理解重点

  • 比较表达式返回同形状的布尔数组
  • 布尔数组可直接作为索引完成无显式循环的过滤
  • mask.sum() 利用 True=1False=0 统计命中个数
  • 多条件必须用 & / | / ~,每个条件必须加括号——(arr >= 3) & (arr <= 7) 而非 arr >= 3 & arr <= 7

常见坑

  1. 整数与浮点混合运算时 NumPy 自动提升为浮点,结果类型可能与预期不同
  2. astype 每次都拷贝,大数组频繁调用是性能瓶颈
  3. 大数组先用 nbytes 估算内存占用量,再决定用哪种 dtype
  4. 布尔组合用 & / | 忘记加括号,会因运算符优先级报 TypeError 或得出错误结果
  5. arr.astype(int) 是截断不是四舍五入——1.91

小结

  • shapedtype 是理解数组的两个核心维度:形状决定了数据组织,类型决定了数值能力
  • 后续所有运算、索引、广播本质上都建立在属性之上
  • 布尔数组是 NumPy 过滤的第一选择,优先于显式 for 循环
  • 养成拿到数组先查 shape + dtype 的习惯