人工智能之數據分析 numpy
第六章 數組基本操作
(文章目錄)
前言
NumPy 提供了豐富而高效的數組基本操作,包括形狀變換、維度調整、連接與分割、元素增刪、翻轉、對角線提取等。這些操作在數據預處理、圖像處理、科學計算中極為常用。
一、修改數組形狀(Reshaping)
1. reshape()
返回一個具有新形狀的視圖(若可能),不改變原數組數據。
import numpy as np
a = np.arange(12) # [0 1 2 ... 11]
b = a.reshape(3, 4)
print(b)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# 自動推斷一個維度(用 -1)
c = a.reshape(2, -1) # 自動計算為 (2, 6)
⚠️ 元素總數必須一致,否則報錯。
2. resize()
直接修改原數組形狀(原地操作),若新尺寸更大,則用 0 填充。
a = np.array([1, 2, 3, 4])
a.resize(2, 3)
print(a)
# [[1 2 3]
# [4 0 0]] ← 自動填充0
注意:
np.resize(a, new_shape)是函數形式,返回新數組,且會循環填充(不是補 0)!
d = np.resize([1,2], (2,3))
# [[1 2 1]
# [2 1 2]] ← 循環重複原始數據
3. ravel() 與 flatten()
將多維數組展平為一維:
| 方法 | 返回 | 是否共享內存 |
|---|---|---|
ravel() |
視圖(若可能) | 是 |
flatten() |
副本 | 否 |
arr = np.array([[1, 2], [3, 4]])
print(arr.ravel()) # [1 2 3 4]
print(arr.flatten()) # [1 2 3 4]
二、修改維度(Adding/Removing Axes)
1. 增加維度:np.newaxis 或 None
x = np.array([1, 2, 3]) # shape: (3,)
y = x[:, np.newaxis] # shape: (3, 1)
z = x[np.newaxis, :] # shape: (1, 3)
2. 刪除長度為 1 的維度:squeeze()
a = np.array([[[1], [2], [3]]]) # shape: (1, 3, 1)
b = a.squeeze() # shape: (3,)
c = a.squeeze(axis=0) # shape: (3, 1)
3. 擴展維度:expand_dims()
x = np.array([1, 2, 3])
y = np.expand_dims(x, axis=1) # shape: (3, 1)
三、數組連接(Concatenation)
1. np.concatenate()
沿指定軸連接多個數組(要求其他維度一致)。
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
# 沿 axis=0(行方向)
np.concatenate([a, b], axis=0)
# [[1 2]
# [3 4]
# [5 6]]
# 沿 axis=1(列方向)→ 需要行數相同
c = np.array([[7], [8], [9]])
np.concatenate([a, c[:2]], axis=1) # 取前兩行
# [[1 2 7]
# [3 4 8]]
2. 快捷函數
np.vstack():垂直堆疊(axis=0)np.hstack():水平堆疊(axis=1)np.dstack():深度堆疊(axis=2)
np.vstack([a, b]) # 等價於 concatenate(..., axis=0)
np.hstack([a, [[7], [8]]]) # 列拼接
💡 對一維數組:
vstack會將其視為行向量(自動升維)hstack直接拼接成更長的一維數組
四、數組分割(Splitting)
1. np.split():等分或按位置分割
arr = np.arange(9)
# 等分為3份
np.split(arr, 3) # [array([0,1,2]), array([3,4,5]), array([6,7,8])]
# 按索引位置分割
np.split(arr, [2, 5]) # 分成 [0:2], [2:5], [5:]
2. 方向專用函數
np.hsplit():水平分割(axis=1)np.vsplit():垂直分割(axis=0)np.dsplit():深度分割(axis=2)
mat = np.arange(12).reshape(3, 4)
np.hsplit(mat, 2) # 分成兩個 (3,2) 數組
五、增減元素
⚠️ NumPy 數組大小固定,這些操作返回新數組,效率較低,應儘量避免頻繁使用。
1. np.append()
在末尾添加元素(自動展平!除非指定 axis)
a = np.array([1, 2, 3])
np.append(a, [4, 5]) # [1 2 3 4 5]
# 多維需指定 axis
b = np.array([[1, 2], [3, 4]])
np.append(b, [[5, 6]], axis=0) # 添加一行
2. np.insert()
在指定位置插入元素
a = np.array([1, 2, 4])
np.insert(a, 2, 3) # 在索引2處插入3 → [1 2 3 4]
np.insert(a, 1, [9, 10]) # 插入多個 → [1 9 10 2 4]
3. np.delete()
刪除指定位置元素
a = np.array([1, 2, 3, 4])
np.delete(a, 1) # 刪除索引1 → [1 3 4]
np.delete(a, [0,2]) # 刪除多個 → [2 4]
六、翻轉數組(Flipping)
| 函數 | 説明 |
|---|---|
np.flip(arr, axis) |
沿指定軸翻轉 |
np.fliplr(arr) |
左右翻轉(axis=1) |
np.flipud(arr) |
上下翻轉(axis=0) |
arr = np.array([[1, 2], [3, 4]])
np.fliplr(arr)
# [[2 1]
# [4 3]]
np.flipud(arr)
# [[3 4]
# [1 2]]
np.flip(arr, axis=None) # 完全翻轉(等價於 arr[::-1, ::-1] 展平後反轉)
七、對角線操作
1. np.diag()
- 從向量構造對角矩陣
- 從矩陣提取對角線
v = np.array([1, 2, 3])
M = np.diag(v)
# [[1 0 0]
# [0 2 0]
# [0 0 3]]
np.diag(M) # [1 2 3]
np.diag(M, k=1) # 上對角線 → [0 0]
2. np.diagonal()
更通用的對角線提取(支持高維)
arr = np.arange(12).reshape(3, 4)
np.diagonal(arr) # [0 5 10]
3. np.trace()
計算對角線元素之和(跡)
np.trace(M) # 1+2+3 = 6
八、其他實用操作
轉置(Transpose)
arr = np.array([[1, 2, 3], [4, 5, 6]])
arr.T # 轉置
arr.transpose() # 等價
np.transpose(arr, axes=(1,0)) # 顯式指定軸順序
排序
a = np.array([3, 1, 4, 1])
np.sort(a) # 返回排序後副本
a.sort() # 原地排序
np.argsort(a) # 返回排序索引
九、小結表:常用操作速查
| 操作類型 | 函數/方法 | 説明 |
|---|---|---|
| 形狀變換 | reshape,resize,ravel,flatten |
改變數組形狀 |
| 維度調整 | np.newaxis,squeeze,expand_dims |
增刪維度 |
| 連接 | concatenate,vstack,hstack |
拼接數組 |
| 分割 | split,hsplit,vsplit |
拆分數組 |
| 增刪元素 | append,insert,delete |
(慎用) |
| 翻轉 | flip,fliplr,flipud |
反轉順序 |
| 對角線 | diag,diagonal,trace |
對角相關 |
| 轉置 | .T,transpose() |
行列互換 |
這些操作構成了 NumPy 數據處理的基礎。在實際項目中,優先使用向量化操作和視圖機制,避免頻繁創建新數組以提升性能。
📌 場景 1:圖像處理 —— 圖像拼接與裁剪
背景
圖像通常表示為三維數組:(height, width, channels),例如 RGB 圖像為 (H, W, 3)。
示例:水平拼接兩張圖像(如對比原圖與濾波結果)
import numpy as np
# 模擬兩張 100x100 的灰度圖(單通道)
img1 = np.random.randint(0, 256, size=(100, 100), dtype=np.uint8)
img2 = np.random.randint(0, 256, size=(100, 100), dtype=np.uint8)
# 水平拼接(左右並排)
combined = np.hstack([img1, img2]) # shape: (100, 200)
# 若是彩色圖(H, W, 3),同樣適用
color1 = np.random.randint(0, 256, size=(100, 100, 3), dtype=np.uint8)
color2 = np.random.randint(0, 256, size=(100, 100, 3), dtype=np.uint8)
color_combined = np.hstack([color1, color2]) # (100, 200, 3)
裁剪圖像中心區域(使用切片)
h, w = img1.shape
crop_h, crop_w = 50, 50
start_h, start_w = (h - crop_h) // 2, (w - crop_w) // 2
cropped = img1[start_h:start_h+crop_h, start_w:start_w+crop_w]
✅ 切片是視圖,內存高效!
📌 場景 2:機器學習 —— 批量數據 reshape 與維度擴展
背景
深度學習框架(如 TensorFlow/PyTorch)要求輸入為 (batch_size, height, width, channels)。
示例:將一維特徵向量轉為“偽圖像”用於 CNN
# 原始數據:1000 個樣本,每個 784 維(如 MNIST 展平後的圖像)
X_flat = np.random.rand(1000, 784)
# 重塑為 28x28 圖像
X_img = X_flat.reshape(-1, 28, 28) # shape: (1000, 28, 28)
# 添加通道維度(灰度圖 → (1000, 28, 28, 1))
X_img = X_img[..., np.newaxis] # 或 X_img.reshape(-1, 28, 28, 1)
print(X_img.shape) # (1000, 28, 28, 1)
增加 batch 維度(單樣本推理)
single_sample = np.random.rand(28, 28)
batch_input = np.expand_dims(single_sample, axis=0) # (1, 28, 28)
📌 場景 3:時間序列分析 —— 滑動窗口分割
背景
將一維時間序列分割為多個重疊窗口,用於 LSTM 或特徵提取。
示例:用 reshape + stride_tricks 或簡單循環實現滑動窗口
def create_sliding_windows(data, window_size, step=1):
"""
將一維數組分割為滑動窗口
"""
n = len(data)
num_windows = (n - window_size) // step + 1
windows = []
for i in range(0, num_windows * step, step):
windows.append(data[i:i+window_size])
return np.array(windows)
# 使用
ts = np.arange(10) # [0 1 2 ... 9]
windows = create_sliding_windows(ts, window_size=4, step=2)
print(windows)
# [[0 1 2 3]
# [2 3 4 5]
# [4 5 6 7]
# [6 7 8 9]]
💡 更高效方式可用
numpy.lib.stride_tricks.sliding_window_view(NumPy ≥1.20):
from numpy.lib.stride_tricks import sliding_window_view
windows = sliding_window_view(ts, window_shape=4)[::2] # 步長為2
📌 場景 4:科學計算 —— 構造對角矩陣與提取對角線
背景
在物理模擬、優化問題中常需構造或操作對角矩陣。
示例:構建帶狀對角矩陣(如有限差分法中的 Laplacian)
n = 5
main_diag = np.full(n, 2.0)
off_diag = np.full(n-1, -1.0)
# 構造三對角矩陣
A = np.diag(main_diag) + np.diag(off_diag, k=1) + np.diag(off_diag, k=-1)
print(A)
# [[ 2. -1. 0. 0. 0.]
# [-1. 2. -1. 0. 0.]
# [ 0. -1. 2. -1. 0.]
# [ 0. 0. -1. 2. -1.]
# [ 0. 0. 0. -1. 2.]]
提取協方差矩陣的方差(對角線)
cov_matrix = np.array([[1.0, 0.2, 0.1],
[0.2, 2.0, 0.3],
[0.1, 0.3, 1.5]])
variances = np.diag(cov_matrix) # [1.0, 2.0, 1.5]
📌 場景 5:數據增強 —— 翻轉圖像(數據擴增)
背景
在訓練 CNN 時,通過對圖像翻轉增加數據多樣性。
image = np.random.rand(32, 32, 3)
# 水平翻轉(左右鏡像)
flipped_lr = np.fliplr(image)
# 垂直翻轉(上下顛倒)
flipped_ud = np.flipud(image)
# 隨機選擇是否翻轉(用於數據增強 pipeline)
if np.random.rand() > 0.5:
image = np.fliplr(image)
✅ 這些操作返回視圖或高效副本,適合實時增強。
📌 場景 6:多傳感器數據融合 —— 數組連接與分割
背景
多個傳感器採集相同時間長度的數據,需合併處理。
# 模擬3個傳感器,各採樣100個時間點
sensor1 = np.random.randn(100)
sensor2 = np.random.randn(100)
sensor3 = np.random.randn(100)
# 合併為 (100, 3) 的特徵矩陣
features = np.column_stack([sensor1, sensor2, sensor3]) # 等價於 hstack 升維後
# 或者用 vstack 轉置
features_alt = np.vstack([sensor1, sensor2, sensor3]).T # shape: (100, 3)
# 分割回原始信號
s1, s2, s3 = features.T # 利用轉置解包
總結:按場景推薦操作
| 應用場景 | 推薦 NumPy 操作 |
|---|---|
| 圖像拼接 | np.hstack,np.vstack |
| 深度學習輸入準備 | reshape,expand_dims,np.newaxis |
| 時間序列窗口 | sliding_window_view, 自定義切片 |
| 物理/數學建模 | np.diag,np.diagonal |
| 數據增強 | np.fliplr,np.flipud,np.flip |
| 多源數據融合 | np.column_stack,np.concatenate,.T |
後續
本文主要講述了numpy數組的基本操作以及應用場景。python過渡項目部分代碼已經上傳至gitee,後續會逐步更新,主要受時間原因限制,當然自己也可以克隆到本地學習拓展。
資料關注
公眾號:咚咚王 gitee:https://gitee.com/wy18585051844/ai_learning
《Python編程:從入門到實踐》 《利用Python進行數據分析》 《算法導論中文第三版》 《概率論與數理統計(第四版) (盛驟) 》 《程序員的數學》 《線性代數應該這樣學第3版》 《微積分和數學分析引論》 《(西瓜書)周志華-機器學習》 《TensorFlow機器學習實戰指南》 《Sklearn與TensorFlow機器學習實用指南》 《模式識別(第四版)》 《深度學習 deep learning》伊恩·古德費洛著 花書 《Python深度學習第二版(中文版)【純文本】 (登封大數據 (Francois Choliet)) (Z-Library)》 《深入淺出神經網絡與深度學習+(邁克爾·尼爾森(Michael+Nielsen)》 《自然語言處理綜論 第2版》 《Natural-Language-Processing-with-PyTorch》 《計算機視覺-算法與應用(中文版)》 《Learning OpenCV 4》 《AIGC:智能創作時代》杜雨+&+張孜銘 《AIGC原理與實踐:零基礎學大語言模型、擴散模型和多模態模型》 《從零構建大語言模型(中文版)》 《實戰AI大模型》 《AI 3.0》