# Python数据分析必备:Numpy数组的5种高效创建方法(附代码示例)
如果你刚开始接触Python数据分析,可能会觉得Numpy这个库有点抽象,尤其是那个听起来很专业的`ndarray`。但别担心,其实它就是我们处理数据时最得力的助手。想象一下,你手头有一堆销售数据需要快速计算平均值、标准差,或者要对图像数据进行批量处理,用Python原生的列表来做这些操作,不仅代码冗长,效率也低得让人抓狂。这时候,Numpy的`ndarray`(N维数组)就派上用场了。
Numpy的核心优势在于它的数组对象`ndarray`,这是一个多维、同质(所有元素类型相同)的数据容器。它底层用C语言实现,能让你用简洁的向量化操作替代繁琐的循环,计算速度提升几个数量级是常有的事。今天我们不谈那些复杂的底层原理,就从最实际的地方入手:**如何快速、高效地创建你需要的数组**。掌握了创建方法,你就拿到了打开高效数据分析大门的钥匙。
这篇文章就是为你准备的。我会带你深入五种最常用、最高效的数组创建方法,每种方法都配有清晰的代码示例和适用场景分析。无论你是要初始化一个全零的矩阵,还是生成一个等间隔的数列,或是从现有的Python数据结构转换,这里都有现成的“配方”。我们直接进入正题。
## 1. 从基础开始:使用 `np.array()` 从Python序列创建
`np.array()` 可能是你接触Numpy时遇到的第一个函数。它的作用很直观:将Python的列表、元组等序列式数据结构,转换成一个Numpy的`ndarray`对象。这个过程不仅仅是简单的“包装”,更重要的是确定了数组的**数据类型(dtype)**和**内存布局**,为后续的高效计算打下基础。
> 注意:`np.array()` 和 `np.ndarray()` 是两个不同的东西。前者是一个用于创建数组的便捷函数,后者是Numpy数组的底层类构造函数。在99%的情况下,你都应该使用 `np.array()` 来创建数组,因为它更安全、更直观。
让我们看几个具体的例子,感受一下它的用法和灵活性:
```python
import numpy as np
# 示例1:从列表创建一维数组
list_data = [1, 2, 3, 4, 5]
arr_from_list = np.array(list_data)
print("从列表创建:", arr_from_list)
print("数据类型:", arr_from_list.dtype) # 通常为 int64 (取决于系统)
# 示例2:从嵌套列表创建二维数组(矩阵)
matrix_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix_arr = np.array(matrix_list)
print("\n二维矩阵:\n", matrix_arr)
print("矩阵形状:", matrix_arr.shape) # 输出 (3, 3)
# 示例3:指定数据类型
# 有时为了节省内存或满足特定计算库的要求,需要明确指定数据类型
float_arr = np.array([1, 2, 3], dtype=np.float32)
complex_arr = np.array([1, 2, 3], dtype=np.complex128)
print("\n指定为float32:", float_arr, "dtype:", float_arr.dtype)
print("指定为复数:", complex_arr, "dtype:", complex_arr.dtype)
# 示例4:控制最小维度
# ndmin参数可以强制数组拥有指定的最小维度
scalar_like = np.array([1, 2, 3], ndmin=2)
print("\n强制为二维(ndmin=2):\n", scalar_like)
print("形状:", scalar_like.shape) # 输出 (1, 3)
```
`np.array()` 函数有几个关键参数决定了最终数组的行为:
- **`dtype`**: 这是最重要的参数之一。Numpy支持比Python更丰富的数字类型,如`int8`, `int16`, `int32`, `int64`, `float16`, `float32`, `float64`, `complex64`, `complex128`等。选择合适的`dtype`可以显著影响内存占用和计算精度。
- **`copy`**: 默认为`True`,意味着会创建数据的副本。如果设置为`False`且输入数据已经是`ndarray`,则可能返回一个视图(view),共享内存。对初学者来说,保持默认的`True`更安全。
- **`order`**: 决定数组在内存中的存储顺序。`'C'`表示C风格的行优先(row-major),`'F'`表示Fortran风格的列优先(column-major)。这会影响某些操作的性能,但通常使用默认的`'K'`(保持输入顺序)即可。
在实际项目中,你可能会从各种来源(如文件读取、API接口)得到Python列表形式的数据。`np.array()`就是你将这些数据“Numpy化”的标准入口。一个常见的坑是,如果列表中的元素类型不一致(如整数和浮点数混合),Numpy会向上转型(type promotion)到更通用的类型(如全部转为浮点数),这可能导致意料之外的内存增加。
## 2. 快速初始化:使用 `np.zeros()`, `np.ones()`, `np.full()` 创建特定值数组
当你需要创建一个特定形状的数组,并且所有元素初始化为同一个值时,Numpy提供了一组非常高效的函数。这在机器学习中初始化权重矩阵、在图像处理中创建掩膜(mask)、或者在模拟中设置初始条件时特别有用。
### 2.1 创建全零数组 `np.zeros()`
全零数组可能是最常用的初始化数组。它的语法非常直接:`np.zeros(shape, dtype=float, order='C')`。
```python
import numpy as np
# 创建一个3行4列的全零浮点数矩阵
zeros_matrix = np.zeros((3, 4))
print("3x4全零矩阵:\n", zeros_matrix)
# 创建一维的零数组,长度为10
zeros_vector = np.zeros(10)
print("\n长度为10的零向量:", zeros_vector)
# 创建三维张量(例如,可以表示RGB图像的批量数据)
zeros_tensor = np.zeros((2, 3, 4)) # 2个深度,每个是3x4的矩阵
print("\n2x3x4全零张量的形状:", zeros_tensor.shape)
print("总元素数:", zeros_tensor.size)
# 指定数据类型为整数
zeros_int = np.zeros((2, 2), dtype=np.int32)
print("\n整数类型的零矩阵:\n", zeros_int)
```
`np.zeros()` 在内存分配后,会显式地将每个字节设置为0。对于数值计算,这提供了一个干净的起点。
### 2.2 创建全一数组 `np.ones()`
全一数组在需要乘法单位元或者构建特定结构的矩阵(如全连接层的初始偏置)时非常方便。其用法与`np.zeros()`完全对称。
```python
import numpy as np
# 创建5x5的全一矩阵(例如,可表示一个全连接的邻接矩阵)
ones_matrix = np.ones((5, 5))
print("5x5全一矩阵:\n", ones_matrix)
# 创建三维全一张量,并指定为半精度浮点数以节省内存(用于某些GPU计算)
ones_half = np.ones((2, 2, 2), dtype=np.float16)
print("\n半精度浮点全一张量:\n", ones_half)
print("数据类型:", ones_half.dtype)
```
### 2.3 创建填充任意值的数组 `np.full()`
如果你需要的初始值不是0或1,而是其他任意标量值,`np.full()`就是你的工具。它的函数签名是`np.full(shape, fill_value, dtype=None, order='C')`。
```python
import numpy as np
# 创建一个5x5的矩阵,所有元素填充为7
full_matrix = np.full((5, 5), 7)
print("填充值为7的5x5矩阵:\n", full_matrix)
# 更实用的例子:初始化一个表示图像掩膜的数组,用255(白色)填充
mask = np.full((480, 640), 255, dtype=np.uint8) # 假设一个640x480的图像
print(f"\n图像掩膜形状: {mask.shape}, 数据类型: {mask.dtype}")
print("左上角像素值:", mask[0, 0])
# 填充特殊值,如NaN(非数字)或Inf(无穷大)
nan_array = np.full((3, 3), np.nan)
inf_array = np.full((2, 2), np.inf)
print("\n填充NaN的数组:\n", nan_array)
print("填充Inf的数组:\n", inf_array)
```
为了更清晰地对比这三个函数,我们用一个表格总结:
| 函数 | 主要用途 | 示例代码 | 典型输出形状 (示例) |
| :--- | :--- | :--- | :--- |
| `np.zeros(shape)` | 初始化全零数组,用于权重初始化、占位符 | `np.zeros((3,3))` | `[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]` |
| `np.ones(shape)` | 初始化全一数组,用于构造单位矩阵、偏置初始化 | `np.ones((2,4))` | `[[1., 1., 1., 1.], [1., 1., 1., 1.]]` |
| `np.full(shape, value)` | 用指定常量填充数组,用于设置特定初始值、掩膜 | `np.full((2,2), 5)` | `[[5, 5], [5, 5]]` |
这三个函数还有一个对应的“_like”版本:`np.zeros_like(a)`, `np.ones_like(a)`, `np.full_like(a, fill_value)`。它们不是根据形状(shape)创建数组,而是根据一个已有数组`a`的形状和数据类型来创建新数组。这在你想创建一个与现有数组维度、类型完全一致的新数组时,可以省去手动指定`shape`和`dtype`的麻烦。
```python
# 使用 _like 系列函数的例子
template_array = np.array([[1, 2], [3, 4]], dtype=np.float64)
new_zeros = np.zeros_like(template_array) # 形状和dtype都与template_array相同
new_full = np.full_like(template_array, fill_value=99)
print("模板数组:\n", template_array)
print("zeros_like结果:\n", new_zeros)
print("full_like结果 (填充99):\n", new_full)
```
## 3. 生成序列:使用 `np.arange()` 和 `np.linspace()` 创建数值范围数组
在很多数值计算和模拟场景中,我们需要生成一个等间隔的数值序列。比如,绘制函数图像时需要定义x轴的范围,或者在进行离散化计算时需要生成采样点。Numpy提供了两个核心函数来满足这类需求:`np.arange()` 和 `np.linspace()`。它们看起来很相似,但设计哲学和适用场景有微妙而重要的区别。
### 3.1 `np.arange()`:基于步长的序列生成
`np.arange()` 的工作方式类似于Python内置的 `range()` 函数,但直接生成一个Numpy数组。它的核心逻辑是:**给定起始值、终止值和步长,生成一个等差数列**。需要注意的是,这个序列是“左闭右开”的,即包含起始值,但不包含终止值。
它的函数签名是:`np.arange([start,] stop[, step,], dtype=None)`。
让我们通过代码来感受它的具体行为:
```python
import numpy as np
# 最基本用法:从0开始,到5结束(不含5),步长为1
arr1 = np.arange(5)
print("np.arange(5):", arr1) # 输出: [0 1 2 3 4]
# 指定起始和结束点
arr2 = np.arange(2, 8)
print("np.arange(2, 8):", arr2) # 输出: [2 3 4 5 6 7]
# 指定起始、结束和步长
arr3 = np.arange(0, 10, 2) # 从0到10,步长为2
print("np.arange(0, 10, 2):", arr3) # 输出: [0 2 4 6 8]
# 使用浮点数步长
arr4 = np.arange(0, 1, 0.2) # 常用于生成概率或比例序列
print("np.arange(0, 1, 0.2):", arr4) # 输出: [0. 0.2 0.4 0.6 0.8]
# 反向序列
arr5 = np.arange(10, 0, -2)
print("np.arange(10, 0, -2):", arr5) # 输出: [10 8 6 4 2]
```
`np.arange()` 的一个潜在问题是处理浮点数步长时可能由于浮点精度问题导致元素个数与预期不符。例如,`np.arange(0, 0.6, 0.2)` 可能因为浮点舍入误差,最后一个值刚好是0.6(理论上应该被排除),或者少一个元素。对于对元素个数有严格要求的情况,`np.linspace()` 是更可靠的选择。
### 3.2 `np.linspace()`:基于元素个数的序列生成
与 `np.arange()` 关注步长不同,`np.linspace()` 的核心是**控制生成序列的元素数量**。它的函数签名是:`np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)`。你可以精确指定需要多少个点,它会自动计算步长。
```python
import numpy as np
# 默认生成50个点
default_arr = np.linspace(0, 10)
print(f"np.linspace(0, 10) 生成了 {len(default_arr)} 个点")
print("前5个点:", default_arr[:5])
# 精确控制生成10个点,包含终点
arr_include = np.linspace(0, 1, num=10, endpoint=True)
print("\nnp.linspace(0, 1, num=10, endpoint=True):")
print(arr_include)
# 生成10个点,不包含终点
arr_exclude = np.linspace(0, 1, num=10, endpoint=False)
print("\nnp.linspace(0, 1, num=10, endpoint=False):")
print(arr_exclude)
# 获取步长信息
arr_with_step, step = np.linspace(0, 10, num=6, retstep=True)
print(f"\n序列: {arr_with_step}")
print(f"计算出的步长: {step}") # 输出 2.0
# 一个实用案例:生成正弦函数的采样点
x = np.linspace(0, 2 * np.pi, 100) # 在0到2π之间均匀采样100个点
y = np.sin(x)
# 现在 x 包含了100个均匀分布的点,非常适合用于绘图或数值积分
```
为了帮助你快速根据需求选择正确的函数,我整理了以下对比表格:
| 特性 | `np.arange(start, stop, step)` | `np.linspace(start, stop, num)` |
| :--- | :--- | :--- |
| **核心参数** | 起始值、终止值、**步长** | 起始值、终止值、**元素个数** |
| **区间包含性** | `[start, stop)` (左闭右开) | 默认 `[start, stop]` (两端都包含),可通过`endpoint`参数控制 |
| **浮点精度** | 可能因浮点舍入误差导致元素个数不精确 | 元素个数精确可控,不受浮点误差影响 |
| **典型用途** | 已知明确步长的序列,如索引序列、固定间隔采样 | 需要精确控制点数,如函数绘图、数值积分、定义坐标轴 |
| **示例** | `np.arange(0, 10, 2)` -> `[0, 2, 4, 6, 8]` | `np.linspace(0, 10, 5)` -> `[0., 2.5, 5., 7.5, 10.]` |
在实际项目中,我的经验法则是:**当你关心序列的“步长”或“间隔”时,用`arange`;当你关心序列的“点数”或“分辨率”时,用`linspace`**。例如,模拟一个时间序列,如果采样频率是100Hz(步长0.01秒),用`arange`;如果知道总时长和需要多少个采样点,用`linspace`。
## 4. 特殊矩阵:使用 `np.eye()`, `np.identity()`, `np.diag()` 创建结构化数组
在线性代数、机器学习以及各种工程计算中,我们经常需要一些具有特殊结构的矩阵,比如单位矩阵、对角矩阵等。Numpy提供了一组函数来快速生成这些矩阵,避免了我们手动填充元素的繁琐。
### 4.1 单位矩阵:`np.eye()` 与 `np.identity()`
单位矩阵是一个方阵,主对角线上的元素全为1,其余元素全为0。在矩阵乘法中,它扮演着数字“1”的角色。Numpy提供了两个函数来创建它。
`np.identity(n)` 创建一个 n×n 的单位矩阵,非常简单直接。
```python
import numpy as np
# 创建一个3x3的单位矩阵
I3 = np.identity(3)
print("3x3单位矩阵 (np.identity):\n", I3)
```
`np.eye(N, M=None, k=0)` 则更加灵活。`N`是行数,`M`是列数(默认为N,即创建方阵)。最关键的是`k`参数,它控制**对角线的偏移**。`k=0`是主对角线,`k>0`是主对角线上方的第k条对角线,`k<0`则是主对角线下方的第|k|条对角线。
```python
import numpy as np
# 创建一个4x4的单位矩阵
eye_square = np.eye(4)
print("4x4单位矩阵:\n", eye_square)
# 创建一个3行5列的矩阵,主对角线为1
eye_rect = np.eye(3, 5)
print("\n3行5列,主对角线为1:\n", eye_rect)
# 使用k参数创建偏移对角线为1的矩阵
# k=1: 主对角线之上的一条对角线
super_diag = np.eye(4, k=1)
print("\n4x4矩阵,k=1 (上对角线):\n", super_diag)
# k=-2: 主对角线之下的第二条对角线
sub_diag = np.eye(5, k=-2)
print("\n5x5矩阵,k=-2 (下第二条对角线):\n", sub_diag)
```
这种偏移对角线的矩阵在表示某些特殊关系(如上三角矩阵的一部分)或构造特定线性算子时非常有用。
### 4.2 对角矩阵:`np.diag()`
`np.diag()` 函数有两种用法,既可以从一个一维数组创建对角矩阵,也可以从一个二维数组中提取对角线元素。
**用法一:将一维数组放在矩阵的对角线上,创建对角矩阵。**
```python
import numpy as np
# 给定一个一维数组,将其元素放在方阵的对角线上
v = np.array([1, 2, 3, 4])
diag_matrix = np.diag(v)
print("向量 v:", v)
print("由v构成的对角矩阵:\n", diag_matrix)
# 输出:
# [[1 0 0 0]
# [0 2 0 0]
# [0 0 3 0]
# [0 0 0 4]]
```
**用法二:从二维矩阵中提取对角线元素,返回一维数组。**
```python
# 从一个现有矩阵中提取主对角线
A = np.array([[10, 20, 30],
[40, 50, 60],
[70, 80, 90]])
main_diag = np.diag(A)
print("矩阵 A:\n", A)
print("A的主对角线元素:", main_diag) # 输出: [10 50 90]
```
和 `np.eye()` 一样,`np.diag()` 也支持 `k` 参数来指定提取或放置哪条对角线。
```python
# 提取上对角线 (k=1) 的元素
super_diag_elements = np.diag(A, k=1)
print("A的上对角线 (k=1) 元素:", super_diag_elements) # 输出: [20 60]
# 创建一个矩阵,将向量放在k=-1的对角线上
sub_diag_matrix = np.diag([9, 8, 7], k=-1)
print("\n将[9,8,7]放在k=-1对角线上的矩阵:\n", sub_diag_matrix)
```
### 4.3 随机矩阵:`np.random` 模块
虽然不属于“创建方法”的严格范畴,但在实际应用中,初始化随机矩阵(例如神经网络的权重)是极其常见的需求。Numpy的 `random` 模块提供了丰富的函数。
```python
import numpy as np
# 设置随机种子以确保结果可复现
np.random.seed(42)
# 生成一个3x4的矩阵,元素服从[0.0, 1.0)区间的均匀分布
random_uniform = np.random.rand(3, 4)
print("均匀分布随机矩阵:\n", random_uniform)
# 生成一个2x2x2的张量,元素服从标准正态分布(均值为0,方差为1)
random_normal = np.random.randn(2, 2, 2)
print("\n标准正态分布随机张量:\n", random_normal)
# 生成一个5x5的矩阵,元素为[1, 10)区间的随机整数
random_int = np.random.randint(1, 10, size=(5, 5))
print("\n[1,10)区间随机整数矩阵:\n", random_int)
```
这些特殊矩阵的创建函数,结合前面介绍的基础方法,已经能够覆盖绝大多数数组初始化场景。它们不仅仅是语法糖,更是高效编程的体现,让你能用一行清晰的代码完成复杂的矩阵构造。
## 5. 从现有数据构造:使用 `np.asarray()`, `np.copy()` 与 `np.fromfunction()`
在真实的数据分析流水线中,数据很少是从零开始“创建”的,更多是从已有的数据源“转换”或“衍生”而来。Numpy提供了一系列函数,让你能灵活地从各种现有数据构造新的数组,同时还能精细地控制内存和行为。
### 5.1 `np.asarray()`:高效的数组转换
`np.asarray()` 是 `np.array()` 的一个轻量级变体。它的核心目标是:**尽可能不复制数据,将输入转换为一个`ndarray`**。如果输入已经是一个`ndarray`,并且满足指定的`dtype`和`order`要求,`np.asarray()` 通常会直接返回输入本身(或它的一个视图),而不是创建一个副本。这可以节省大量内存和计算时间。
```python
import numpy as np
# 场景1:输入已经是ndarray,asarray通常不复制
original = np.ones((3, 3))
asarray_result = np.asarray(original)
print("original is asarray_result:", original is asarray_result) # 输出: True,是同一个对象
# 场景2:输入是Python列表,asarray会创建新的ndarray(此时行为类似array)
list_data = [1, 2, 3]
from_list = np.asarray(list_data)
print("\n从列表转换:", from_list)
print("list_data is from_list:", list_data is from_list) # False,创建了新对象
# 场景3:指定dtype,如果输入数组的dtype不匹配,则会发生复制和转换
float_arr = np.array([1.1, 2.2, 3.3])
int_arr = np.asarray(float_arr, dtype=np.int32) # dtype不匹配,触发复制和类型转换
print("\n原始浮点数组:", float_arr)
print("转换为int32:", int_arr) # 输出: [1 2 3] (截断小数部分)
print("它们是同一个对象吗?", float_arr is int_arr) # False
```
> 提示:当你编写一个函数,它既可以接受Numpy数组也可以接受类似数组的对象(如列表)作为输入,并且你希望内部统一使用Numpy数组进行计算时,`np.asarray()` 是首选。它避免了在输入已经是数组时不必要的复制。
### 5.2 `np.copy()` 与视图(View)的概念
理解Numpy中的**复制(copy)**和**视图(view)**至关重要,它直接关系到代码的内存效率和可能出现的隐蔽bug。简单来说:
- **复制**:创建一个全新的数组对象,拥有独立的数据缓冲区。对新数组的修改不会影响原数组。
- **视图**:创建一个新的数组对象,但它与原数组**共享数据缓冲区**。通过视图修改数据,原数组的数据也会改变。
`np.copy()` 函数(或数组的 `.copy()` 方法)用于创建数组的**深拷贝**。
```python
import numpy as np
original = np.array([[1, 2, 3], [4, 5, 6]])
# 使用 .copy() 方法创建深拷贝
deep_copy = original.copy()
deep_copy[0, 0] = 99 # 修改拷贝
print("原数组:\n", original)
print("深拷贝(修改后):\n", deep_copy)
# 可以看到原数组的[0,0]元素仍然是1,没有被修改
# 对比:切片操作通常返回的是视图
view = original[:] # 这创建了一个视图
view[0, 1] = 88 # 通过视图修改数据
print("\n通过视图修改后,原数组:\n", original) # 原数组的[0,1]也被改成了88
```
那么,什么时候该用复制,什么时候可以用视图呢?我的经验是:
- **需要复制的情况**:当你需要对一个数组进行修改,但又必须保留原始数据不变时。例如,对数据进行归一化预处理,你需要一份副本进行操作,保留原始数据用于后续对比或不同处理。
- **可以使用视图的情况**:当你只是需要以不同的形状或切片访问同一份数据,且不打算(或允许)修改原始数据时。视图非常高效,因为它避免了数据复制。
### 5.3 `np.fromfunction()`:基于函数规则创建数组
这是一个非常强大但有时被忽视的函数。`np.fromfunction(function, shape, **kwargs)` 会根据你提供的函数和形状来构造数组。对于数组中的每个坐标 `(i, j, k, ...)`,它会调用你定义的函数,并将该坐标作为参数传入,函数的返回值就是该位置数组元素的值。
这让你可以用声明式的方法来定义数组内容,代码非常优雅。
```python
import numpy as np
# 示例1:创建一个5x5的矩阵,每个元素的值是其行索引和列索引的和
def sum_of_indices(i, j):
return i + j
matrix_sum = np.fromfunction(sum_of_indices, (5, 5), dtype=int)
print("元素值为 (行索引+列索引) 的矩阵:\n", matrix_sum)
# 示例2:创建一个10x10的矩阵,表示到中心点(4.5, 4.5)的欧氏距离
def distance_from_center(i, j, center_x=4.5, center_y=4.5):
return np.sqrt((i - center_x)**2 + (j - center_y)**2)
distance_matrix = np.fromfunction(distance_from_center, (10, 10))
print("\n到中心点距离矩阵 (左上角):\n", distance_matrix[:3, :3]) # 打印一部分
# 示例3:创建一个3维数组,每个元素是三个坐标的乘积
def product(i, j, k):
return i * j * k
tensor_3d = np.fromfunction(product, (3, 4, 5), dtype=int)
print(f"\n3D张量形状: {tensor_3d.shape}")
print("张量[1,2,3]位置的值:", tensor_3d[1, 2, 3]) # 应该是 1*2*3 = 6
```
`np.fromfunction()` 特别适合创建那些元素值由其在数组中的位置决定的矩阵,比如距离矩阵、网格坐标、以及各种数学变换的模板。它把循环和索引的计算封装了起来,让代码意图更清晰。
### 5.4 从字节或文件创建:`np.frombuffer()` 和 `np.fromfile()`
在处理底层数据流或特定格式的文件时,你可能需要直接从字节或二进制文件创建数组。Numpy也提供了相应的支持。
```python
import numpy as np
# np.frombuffer: 将字节缓冲区解释为数组
# 假设我们从某个网络协议或硬件接口收到一串表示浮点数的字节
byte_data = b'\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@' # 对应 [1.0, 2.0, 3.0] 的字节表示
arr_from_buffer = np.frombuffer(byte_data, dtype=np.float64)
print("从字节缓冲区创建的数组:", arr_from_buffer)
# np.fromfile: 从二进制文件读取(需要先创建一个示例文件)
# 首先,我们创建一个临时的二进制文件并写入一些数据
sample_data = np.arange(10, dtype=np.float32)
sample_data.tofile('temp_binary.dat') # 将数组写入文件
# 然后从文件读回
arr_from_file = np.fromfile('temp_binary.dat', dtype=np.float32)
print("\n从二进制文件读取的数组:", arr_from_file)
# 清理临时文件
import os
os.remove('temp_binary.dat')
```
这些方法在涉及高性能I/O、处理原始传感器数据或与C/C++库交互时非常有用。
掌握了这五种创建Numpy数组的核心方法,你就拥有了应对各种数据初始化场景的工具箱。从最基础的列表转换,到快速初始化特定值数组,再到生成数值序列、构造特殊矩阵,最后到从现有数据灵活转换,它们构成了Numpy数据准备的基石。在实际项目中,这些方法往往会组合使用。例如,你可能先用 `np.zeros()` 初始化一个权重矩阵,然后用 `np.random.randn()` 生成的随机数去填充它,最后用 `np.asarray()` 确保它被送入某个计算函数时是标准的`ndarray`格式。理解每种方法的特点和适用场景,能让你在编写数据分析代码时更加得心应手,写出既高效又清晰的程序。