在數據處理中,我們經常需要調整數組的形狀以滿足不同的需求,比如將二維數據轉換爲一維,或者改變矩陣的行列數。Numpy提供了兩個非常實用的方法:reshapeflatten,它們能輕鬆實現數組變形。本文將從零開始,用最簡單的方式講解這兩個方法的用法。

一、數組變形的基礎

首先,我們需要明確一個核心前提:數組變形前後,元素的總數必須保持一致。比如一個包含12個元素的數組,無論你把它變成(3,4)、(4,3)還是(12,1),總元素數都必須是12,否則會報錯。

舉個例子,假設我們有一個1維數組:

import numpy as np

# 創建一個1維數組,包含12個元素(0到11)
arr = np.arange(12)
print("原數組:", arr)
print("原數組形狀:", arr.shape)  # 輸出:(12,),表示1維12個元素

二、reshape:改變數組形狀

reshape方法可以將數組從當前形狀轉換爲指定的新形狀,但不會改變原數組的元素順序和總數。它的語法是 arr.reshape(new_shape),其中 new_shape 是一個元組(如 (行數, 列數))。

1. 基本用法:指定新形狀

比如我們想把12個元素的數組變成3行4列的二維數組:

# 將1維數組reshape爲3行4列
arr_3x4 = arr.reshape(3, 4)
print("reshape(3,4)後的數組:\n", arr_3x4)
print("新形狀:", arr_3x4.shape)  # 輸出:(3,4)

輸出結果:

reshape(3,4)後的數組:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
新形狀: (3, 4)

2. 參數-1:自動計算缺失維度

如果我們不確定某個維度的大小,可以用 -1 讓Numpy自動計算。比如,我們想把12個元素的數組變成3行,列數自動計算:

# 用-1自動計算列數(總元素數12,3行 → 12/3=4列)
arr_3x_any = arr.reshape(3, -1)
print("reshape(3,-1)後的數組:\n", arr_3x_any)
print("形狀:", arr_3x_any.shape)  # 輸出:(3,4)

3. 注意:原數組不變

reshape 會返回一個新數組,不會修改原數組。這一點很重要,比如原數組 arr 的形狀仍然是 (12,)

print("原數組形狀:", arr.shape)  # 仍然是 (12,)

三、flatten:展平爲1維數組

當我們需要把多維數組(比如二維、三維)變成1維數組時,flatten 就派上用場了。它會將數組“平鋪”成一行,並且返回一個新數組(不會修改原數組)。

1. 基本用法:直接展平

對剛纔的3x4二維數組進行展平:

# 將3x4數組展平爲1維
arr_flat = arr_3x4.flatten()
print("flatten後的數組:", arr_flat)
print("形狀:", arr_flat.shape)  # 輸出:(12,)

輸出結果:

flatten後的數組: [ 0  1  2  3  4  5  6  7  8  9 10 11]
形狀: (12,)

2. 與ravel的區別(簡單瞭解)

Numpy還有一個類似的方法 ravel,它和 flatten 的區別是:
- flatten 返回新數組(副本),修改不會影響原數組;
- ravel 返回原數組的視圖(淺拷貝),修改可能影響原數組。

對初學者來說,flatten 更安全,推薦優先使用。

四、常見錯誤與解決

最容易遇到的錯誤是 “reshape後的總元素數不匹配”。比如,把12個元素的數組reshape成(3,5)(3×5=15≠12):

arr.reshape(3,5)  # 報錯!ValueError: cannot reshape array of size 12 into shape (3,5)

解決方法:檢查 reshape 參數的乘積是否等於原數組的元素總數(即 原數組.size)。

五、綜合示例:從創建到變形

讓我們完整演示一個流程:

# 1. 創建一個6個元素的1維數組
arr = np.arange(6)
print("原數組:", arr, "形狀:", arr.shape)  # (6,)

# 2. reshape成2行3列的二維數組
arr_2x3 = arr.reshape(2, 3)
print("\nreshape(2,3)後:\n", arr_2x3, "形狀:", arr_2x3.shape)

# 3. 用flatten展平爲1維數組
arr_flat = arr_2x3.flatten()
print("\nflatten後:", arr_flat, "形狀:", arr_flat.shape)

輸出結果:

原數組: [0 1 2 3 4 5] 形狀: (6,)

reshape(2,3)後:
 [[0 1 2]
 [3 4 5]] 形狀: (2, 3)

flatten後: [0 1 2 3 4 5] 形狀: (6,)

六、總結

  • reshape:改變數組形狀,元素總數不變,-1 可自動計算缺失維度;
  • flatten:將數組展平爲1維,返回新數組,不會影響原數組;
  • 核心原則:變形前後元素總數必須一致。

掌握這兩個方法,你就能靈活處理數組的形狀,爲後續的數據處理(如機器學習、數據分析)打下基礎!

小夜