np.array 和 np.ndarray 是 NumPy 中两个密切相关但用途和行为完全不同的概念。理解它们的关系是掌握 NumPy 的关键之一。
🔹 1. np.ndarray:NumPy 数组的底层类(类型)
numpy.ndarray是 所有 NumPy 数组对象的实际 Python 类型。- 它是一个类(class),定义了数组的数据结构、属性(如
.shape,.dtype)和方法(如.sum(),.reshape())。 - 所有通过 NumPy 创建的数组,其类型都是
numpy.ndarray。
import numpy as npa = np.array([1, 2, 3])
print(type(a)) # <class 'numpy.ndarray'>
print(isinstance(a, np.ndarray)) # True
✅ 所有 NumPy 数组都是
np.ndarray的实例。
🔹 2. np.array:创建 ndarray 对象的函数
np.array()是一个工厂函数(function),用于从 Python 列表、元组或其他可迭代对象创建一个新的ndarray实例。- 它会自动推断数据类型,并初始化数据内容。
arr = np.array([1, 2, 3]) # 推荐方式!
print(arr) # [1 2 3]
print(type(arr)) # <class 'numpy.ndarray'>
✅
np.array()是你日常创建数组的主要方式。
🔸 关键区别总结
| 特性 | np.array |
np.ndarray |
|---|---|---|
| 类型 | 函数(callable) | 类(class) |
| 用途 | 创建并初始化数组 | 定义数组的类型和行为 |
| 数据初始化 | ✅ 自动用输入数据初始化 | ❌ 不初始化(可能含垃圾值) |
| 使用频率 | ⭐⭐⭐⭐⭐ 日常首选 | ⭐ 很少直接使用 |
| 安全性 | 安全、可靠 | 危险(未初始化内存) |
🔸 为什么不推荐直接用 np.ndarray(...)?
虽然你可以直接调用 np.ndarray 构造函数,但它不会用你的数据初始化数组内容,而是分配一块内存(可能包含任意垃圾值),除非你显式传入 buffer。
示例对比:
# ✅ 正确方式:使用 np.array
a = np.array([1, 2, 3])
print(a) # [1 2 3]# ⚠️ 危险方式:直接调用 np.ndarray
b = np.ndarray(shape=(3,), dtype=int)
print(b) # 可能输出 [123456789 0 -987654321] —— 垃圾值!# 如果非要初始化,需手动赋值或用 buffer(复杂且不直观)
c = np.ndarray(shape=(3,), dtype=int, buffer=np.array([1,2,3]))
print(c) # [1 2 3] —— 但何必这么麻烦?
📌 官方文档明确建议:优先使用
np.array()、np.zeros()、np.ones()等函数创建数组,不要直接实例化np.ndarray。
🔸 类比理解(帮助记忆)
可以把它们类比为:
np.ndarray≈ “汽车的设计图纸/类”np.array()≈ “汽车制造厂的生产线函数”
你想开一辆车,应该去生产线下单(np.array([1,2,3])),而不是自己拿着图纸去拼装底盘(np.ndarray(...))——后者既麻烦又容易出错。
✅ 最佳实践
- 总是使用
np.array()来从已有数据创建数组。 - 使用
np.zeros(),np.ones(),np.empty(),np.full()等来创建特定初始值的数组。 - 不要直接调用
np.ndarray(),除非你在写非常底层的代码(比如自定义数组子类),且知道自己在做什么。
🔚 总结一句话:
np.array是创建ndarray对象的推荐函数;np.ndarray是所有 NumPy 数组的底层类类型。日常编程中,你几乎只用np.array,而不需要直接碰np.ndarray。