爲什麼學Numpy數組?¶
在Python數據分析和科學計算中,Numpy是基礎中的基礎。它提供了高效的多維數組對象,能讓我們像處理簡單數據一樣操作複雜的數值集合,而且運算速度比純Python列表快得多。要深入理解Numpy,必須掌握數組的結構(shape)、如何訪問元素(索引)和如何截取子數組(切片),這也是本文的核心內容。
一、數組的創建:從基礎開始¶
要操作數組,首先得創建它。Numpy提供了多種創建數組的方法,初學者可以從這幾個最常用的開始:
1. np.array():從Python列表創建¶
import numpy as np
# 1維數組(向量)
arr1 = np.array([1, 2, 3, 4, 5])
print("1維數組:", arr1)
# 2維數組(矩陣)
arr2 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("2維數組:\n", arr2)
2. 快速創建全0/全1數組¶
# 3行4列的全0數組
zeros = np.zeros((3, 4)) # shape=(3,4)
print("全0數組:\n", zeros)
# 2行5列的全1數組
ones = np.ones((2, 5))
print("全1數組:\n", ones)
3. np.arange():類似Python的range¶
# 從0到9,步長爲2(生成數組[0,2,4,6,8])
arange_arr = np.arange(0, 10, 2)
print("arange數組:", arange_arr)
二、shape:數組的“維度身份證”¶
shape是Numpy數組的核心屬性,它告訴我們數組的維度信息(比如“幾行幾列”)。理解shape是處理數組的第一步。
1. 查看shape¶
用 .shape 屬性查看數組的形狀:
print("arr1的shape:", arr1.shape) # 輸出 (5,) → 1維數組,長度5
print("arr2的shape:", arr2.shape) # 輸出 (3, 3) → 3行3列的矩陣
2. 修改shape:reshape()¶
reshape() 可以調整數組的維度,但總元素數必須不變。例如:
# 將1維數組轉爲2行3列(原長度5?不行!必須保證總元素數不變)
# 修正:arange_arr是5個元素,reshape(2,3)會報錯。換個例子:
arr3 = np.arange(6) # [0,1,2,3,4,5],shape=(6,)
arr3_reshaped = arr3.reshape(2, 3) # 轉爲2行3列
print("reshape後的數組:\n", arr3_reshaped)
print("新shape:", arr3_reshaped.shape) # (2, 3)
關鍵點:¶
reshape()只是調整維度,不會改變數據順序(C-style行優先)。- 如果想轉成1行多列,可以用
reshape(1, -1)(-1表示自動計算列數)。
三、索引:訪問數組元素¶
索引就像“鑰匙”,讓我們能精準找到數組中的某個元素。Numpy數組的索引規則和Python列表類似,但支持更簡潔的多維度索引。
1. 1維數組索引¶
和Python列表一樣,1維數組的索引從0開始,支持正負索引(負索引表示“倒數第幾個”):
print("arr1[0] =", arr1[0]) # 第一個元素:1
print("arr1[-1] =", arr1[-1]) # 最後一個元素:5
print("arr1[2] =", arr1[2]) # 第三個元素:3
2. 2維數組索引¶
2維數組需要兩個索引(行索引,列索引),用逗號分隔:
# arr2 = [[1,2,3], [4,5,6], [7,8,9]]
print("arr2[1, 2] =", arr2[1, 2]) # 第2行(索引1)第3列(索引2)→ 6
print("arr2[0, 0] =", arr2[0, 0]) # 第1行第1列 → 1
print("arr2[-1, -1] =", arr2[-1, -1]) # 最後一行最後一列 → 9
注意:¶
- 不要寫成
arr2[1][2](雖然Python列表嵌套也支持,但Numpy數組更推薦arr[i,j],效率更高)。
四、切片:截取子數組¶
切片允許我們批量提取元素,形成一個“子數組”。語法是 [start:end:step],其中 start 是起始位置,end 是結束位置(不包含),step 是步長。
1. 1維數組切片¶
# arr1 = [1,2,3,4,5]
print("arr1[1:4] =", arr1[1:4]) # 從索引1到4(不含4)→ [2,3,4]
print("arr1[::2] =", arr1[::2]) # 步長2 → [1,3,5]
print("arr1[:3] =", arr1[:3]) # 省略start → 前3個元素 → [1,2,3]
print("arr1[::] =", arr1[::]) # 省略step和start/end → 整個數組
2. 2維數組切片¶
2維數組切片需要分別指定行切片和列切片,用逗號分隔:
# arr2 = [[1,2,3], [4,5,6], [7,8,9]]
print("arr2[1:3, 0:2] = \n", arr2[1:3, 0:2])
# 解釋:取第1-3行(不含3),第0-2列(不含2) → [[4,5], [7,8]]
print("arr2[:, 1] =", arr2[:, 1]) # 所有行,第1列 → [2,5,8]
print("arr2[0:2, :] = \n", arr2[0:2, :]) # 前2行,所有列 → [[1,2,3], [4,5,6]]
3. 切片的“視圖”特性¶
Numpy切片默認返回的是原數組的“視圖”(共享數據內存),修改子數組會影響原數組:
sub_arr = arr2[1:3, 0:2] # 子數組
sub_arr[0, 0] = 100 # 修改子數組
print("修改後原數組:\n", arr2) # 原數組的[1,0]位置也被修改爲100
如何避免修改原數組?¶
用 .copy() 方法創建獨立的拷貝:
sub_arr = arr2[1:3, 0:2].copy() # 拷貝子數組
sub_arr[0, 0] = 200 # 修改拷貝,原數組不變
print("原數組未被修改:\n", arr2)
五、總結與練習建議¶
- shape:理解數組的維度,用
reshape()調整維度。 - 索引:1維數組類似列表,2維數組需行+列雙索引,支持正負索引。
- 切片:通過
[start:end:step]截取子數組,注意視圖與拷貝的區別。
練習:嘗試用Numpy創建一個5x5的隨機數組,然後:
1. 查看它的shape;
2. 用索引訪問第3行第4列的元素;
3. 用切片截取前3行前3列的子數組;
4. 對切片後的子數組修改,觀察原數組是否變化。
通過動手實踐,你會更快掌握Numpy數組的核心操作!