
- NumPy 教程
- NumPy - 首頁
- NumPy - 簡介
- NumPy - 環境
- NumPy 陣列
- NumPy - Ndarray 物件
- NumPy - 資料型別
- NumPy 建立和運算元組
- NumPy - 陣列建立例程
- NumPy - 陣列操作
- NumPy - 從現有資料建立陣列
- NumPy - 從數值範圍建立陣列
- NumPy - 遍歷陣列
- NumPy - 陣列重塑
- NumPy - 連線陣列
- NumPy - 堆疊陣列
- NumPy - 分割陣列
- NumPy - 扁平化陣列
- NumPy - 轉置陣列
- NumPy 索引和切片
- NumPy - 索引和切片
- NumPy - 高階索引
- NumPy 陣列屬性和操作
- NumPy - 陣列屬性
- NumPy - 陣列形狀
- NumPy - 陣列大小
- NumPy - 陣列步長
- NumPy - 陣列元素大小
- NumPy - 廣播
- NumPy - 算術運算
- NumPy - 陣列加法
- NumPy - 陣列減法
- NumPy - 陣列乘法
- NumPy - 陣列除法
- NumPy 高階陣列操作
- NumPy - 交換陣列軸
- NumPy - 位元組交換
- NumPy - 複製和檢視
- NumPy - 元素級陣列比較
- NumPy - 過濾陣列
- NumPy - 連線陣列
- NumPy - 排序、搜尋和計數函式
- NumPy - 搜尋陣列
- NumPy - 陣列的並集
- NumPy - 查詢唯一行
- NumPy - 建立日期時間陣列
- NumPy - 二元運算子
- NumPy - 字串函式
- NumPy - 數學函式
- NumPy - 統計函式
- NumPy - 矩陣庫
- NumPy - 線性代數
- NumPy - Matplotlib
- NumPy - 使用 Matplotlib 繪製直方圖
- NumPy - NumPy 的 I/O
- NumPy 排序和高階操作
- NumPy - 陣列排序
- NumPy - 沿軸排序
- NumPy - 使用花式索引排序
- NumPy - 結構化陣列
- NumPy - 建立結構化陣列
- NumPy - 操作結構化陣列
- NumPy - 欄位訪問
- NumPy - 記錄陣列
- Numpy - 載入陣列
- Numpy - 儲存陣列
- NumPy - 將值追加到陣列
- NumPy - 交換陣列的列
- NumPy - 向陣列插入軸
- NumPy 處理缺失資料
- NumPy - 處理缺失資料
- NumPy - 識別缺失值
- NumPy - 刪除缺失資料
- NumPy - 填充缺失資料
- NumPy 效能最佳化
- NumPy - 使用陣列進行效能最佳化
- NumPy - 使用陣列進行向量化
- NumPy - 陣列的記憶體佈局
- Numpy 線性代數
- NumPy - 線性代數
- NumPy - 矩陣庫
- NumPy - 矩陣加法
- NumPy - 矩陣減法
- NumPy - 矩陣乘法
- NumPy - 元素級矩陣運算
- NumPy - 點積
- NumPy - 矩陣求逆
- NumPy - 行列式計算
- NumPy - 特徵值
- NumPy - 特徵向量
- NumPy - 奇異值分解
- NumPy - 求解線性方程組
- NumPy - 矩陣範數
- NumPy 元素級矩陣運算
- NumPy - 求和
- NumPy - 求平均值
- NumPy - 求中位數
- NumPy - 求最小值
- NumPy - 求最大值
- NumPy 集合運算
- NumPy - 唯一元素
- NumPy - 交集
- NumPy - 並集
- NumPy - 差集
- NumPy 有用資源
- NumPy 編譯器
- NumPy - 快速指南
- NumPy - 有用資源
- NumPy - 討論
NumPy - 使用陣列進行效能最佳化
使用陣列進行效能最佳化
使用陣列進行效能最佳化包括提高陣列操作的效率,例如減少計算時間和記憶體使用。
我們應該出於以下原因最佳化效能:
- 速度: 更快的計算速度帶來更快的結果和更靈敏的應用程式。
- 可擴充套件性: 最佳化的程式碼可以有效地處理更大的資料集和更復雜的操作。
- 資源效率: 減少記憶體使用和計算開銷。
使用向量化運算
向量化運算指的是能夠一步執行整個陣列或矩陣上的運算,而無需使用顯式迴圈。
這是透過廣播和內部最佳化實現的,使這些運算更快、更高效。
示例
在以下示例中,我們使用 NumPy 的陣列運算對兩個大型陣列“a”和“b”執行向量化加法。此運算計算陣列的元素級和並將結果儲存在新陣列“c”中:
import numpy as np # Create two large arrays a = np.random.rand(1000000) b = np.random.rand(1000000) # Vectorized addition c = a + b print (c)
以下是獲得的輸出:
[0.91662816 0.65486861 1.60409272 ... 0.95122935 1.12795861 0.15812103]
利用高效的資料型別
為陣列選擇合適的資料型別對於最佳化 NumPy 中的效能和記憶體使用非常重要。
例如,使用np.float32而不是np.float64可以顯著影響記憶體使用和效能,尤其是在處理大型資料集時。
在 NumPy 中,資料型別(或 dtype)定義了陣列儲存的元素型別以及儲存每個元素所需的儲存空間。
示例
在此示例中,我們演示了透過建立具有雙精度(64 位)浮點數的陣列,然後使用 astype() 方法將其轉換為單精度(32 位)來使用精度更改:
import numpy as np # Create an array with double precision (64-bit) arr_double = np.array([1.0, 2.0, 3.0], dtype=np.float64) # Print the original double precision array print("Original double precision array:") print(arr_double) print("Data type:", arr_double.dtype) # Convert to single precision (32-bit) arr_single = arr_double.astype(np.float32) # Print the converted single precision array print("\nConverted single precision array:") print(arr_single) print("Data type:", arr_single.dtype)
這將產生以下結果:
Original double precision array: [1. 2. 3.] Data type: float64 Converted single precision array: [1. 2. 3.] Data type: float32
避免使用 NumPy 函式的迴圈
在 NumPy 中,主要優勢之一是可以避免使用內建函式和陣列運算顯式迴圈。這種方法通常稱為向量化。
透過使用 NumPy 函式,您可以一次對整個陣列執行運算,這與使用迴圈相比更加簡潔。
示例
在下面的示例中,我們使用 np.mean() 函式計算陣列元素的平均值,而無需使用任何顯式迴圈:
import numpy as np # Create an array arr = np.array([1, 2, 3, 4, 5]) # Calculate the mean of array elements mean = np.mean(arr) print("mean:",mean)
以下是上述程式碼的輸出:
mean: 3.0
使用廣播進行向量化
廣播指的是能夠對形狀不同的陣列執行元素級運算。它遵循一組規則來確定如何對形狀不同的陣列進行對齊以進行運算:
- 相同維度: 如果陣列具有不同的維度,則較小陣列的形狀在左側填充 1,直到兩個形狀具有相同的長度。
- 維度相容性: 當兩個維度相等或其中一個為 1 時,它們是相容的。對於每個維度,如果大小不同,並且如果它們都不為 1,則廣播失敗。
- 拉伸: 尺寸為 1 的陣列沿該尺寸拉伸以匹配另一個數組尺寸的大小。
示例
在以下示例中,我們廣播“array_1d”以匹配“array_2d”的形狀,從而允許元素級加法:
import numpy as np # Create a 2D array and a 1D array array_2d = np.array([[1, 2, 3], [4, 5, 6]]) array_1d = np.array([10, 20, 30]) # Add the 1D array to each row of the 2D array result = array_2d + array_1d print(result)
獲得的輸出如下所示:
[[11 22 33] [14 25 36]]
就地運算用於向量化
NumPy 中的就地運算指的是直接修改陣列的資料,而無需建立新陣列來儲存結果,從而節省記憶體並提高效能。
這是透過使用修改原始陣列內容的運算子和函式來實現的。這些運算通常使用帶就地字尾的運算子(例如,+=、-=、*=、/=)或支援就地修改的函式。
示例:使用就地運算子
在此示例中,我們直接對陣列應用算術運算“+=”而無需建立新的陣列:
import numpy as np # Create an array arr = np.array([1, 2, 3, 4, 5]) # Add 10 to each element in-place arr += 10 print(arr)
執行上述程式碼後,我們得到以下輸出:
[11 12 13 14 15]
示例:使用就地函式
在這裡,我們使用 NumPy exp() 函式就地計算陣列中每個元素的指數值:
import numpy as np # Create an array with a floating-point data type arr = np.array([1, 2, 3, 4, 5], dtype=np.float64) # Compute the exponential of each element in-place np.exp(arr, out=arr) print(arr)
執行上述程式碼後,我們得到以下輸出:
[ 2.71828183 7.3890561 20.08553692 54.59815003 148.4131591 ]
使用記憶體檢視進行向量化
記憶體檢視指的是訪問或檢視陣列中相同底層資料的不同方式,而無需複製它。此概念允許您建立陣列的不同“檢視”或“切片”,這些檢視可以以各種方式操作相同的資料:
- 切片: 當您切片陣列時,NumPy 會建立原始陣列的檢視,而不是副本。此檢視共享相同的記憶體緩衝區,因此對檢視的更改會影響原始陣列,反之亦然。
- 重塑: 重塑陣列會建立具有不同形狀的相同資料的新的檢視。這不會更改底層資料,但會更改其解釋方式。
示例:切片
在下面的示例中,我們建立了一個二維 NumPy 陣列和原始陣列的檢視(切片)。修改檢視也會影響原始陣列:
import numpy as np # Create a 2D array arr = np.array([[1, 2, 3], [4, 5, 6]]) # Create a view (slice) of the original array view = arr[:, 1:] # Modify the view view[0, 0] = 99 print(arr)
我們得到如下所示的輸出:
[[ 1 99 3] [ 4 5 6]]
示例:重塑
在這裡,我們使用 arange() 函式建立一個一維 NumPy 陣列,然後將其重塑為一個具有 3 行 4 列的二維陣列,更改其結構同時保留原始資料:
import numpy as np # Create a 1D array arr = np.arange(12) # Reshape to a 2D array reshaped = arr.reshape((3, 4)) print(reshaped)
我們得到如下所示的輸出:
[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]
使用步長進行向量化
步長是一個元組,指示遍歷陣列時每個維度要步進的位元組數。它們確定如何在記憶體中訪問陣列元素,從而深入瞭解資料的佈局和訪問方式。
步長為您提供每個維度的記憶體偏移量。例如,在二維陣列中,第二個維度的步長告訴您在記憶體中移動多少位元組才能訪問該行中的下一個元素。
示例
在以下示例中,我們建立了一個二維 NumPy 陣列,並使用strides屬性檢索遍歷陣列時每個維度要步進的位元組數:
import numpy as np # Create a 2D array arr = np.array([[1, 2, 3], [4, 5, 6]]) # Print the strides of the array print(arr.strides)
我們得到如下所示的輸出:
(24, 8)