python3 numpy的一些小知識點
簡介
一個用python實現的科學計算,包括:
1、一個強大的N維數組對象Array;
2、比較成熟的(廣播)函數庫;
3、用于整合C/C++和Fortran代碼的工具包;
4、實用的線性代數、傅里葉變換和隨機數生成函數。
numpy和稀疏矩陣運算包scipy配合使用更加方便。NumPy(Numeric Python)提供了許多高級的數值編程工具,如:矩陣數據類型、矢量處理,以及精密的運算庫。專為進行嚴格的數字處理而產生。多為很多大型金融公司使用,以及核心的科學計算組織如:Lawrence Livermore,NASA用其處理一些本來使用C++,Fortran或Matlab等所做的任務。
NumPy 的前身為 Numeric ,最早由 Jim Hugunin 與其它協作者共同開發,2005 年,Travis Oliphant 在 Numeric 中結合了另一個同性質的程序庫 Numarray 的特色,并加入了其它擴展而開發了 NumPy。NumPy 為開放源代碼并且由許多協作者共同維護開發。
使用方法
NumPy 是一個強大的 Python 庫,廣泛用于科學計算和數據處理。以下是一些 NumPy 在數據處理時常用的主要函數,以及使用時的注意事項:
主要函數
-
數組創建
np.array(): 從列表或元組創建數組。np.zeros(): 創建全零數組。np.ones(): 創建全一數組。np.arange(): 創建等間隔的數組。np.linspace(): 創建指定數量的等間隔數組。
-
數組操作
np.reshape(): 改變數組的形狀。np.flatten(): 將多維數組展平為一維數組。np.transpose(): 轉置數組。np.concatenate(): 連接多個數組。np.split(): 分割數組。
-
數組運算
np.add(),np.subtract(),np.multiply(),np.divide(): 基本的算術運算。np.dot(): 矩陣乘法。np.sum(): 計算數組的和。np.mean(): 計算數組的均值。np.std(): 計算標準差。np.min(),np.max(): 計算最小值和最大值。
-
索引和切片
- 使用
[]進行數組索引。 - 使用
:進行切片。 - 布爾索引:通過條件生成布爾數組來篩選數據。
- 使用
-
線性代數
np.linalg.inv(): 計算矩陣的逆。np.linalg.det(): 計算矩陣的行列式。np.linalg.eig(): 計算特征值和特征向量。
-
隨機數生成
np.random.rand(): 生成均勻分布的隨機數。np.random.randn(): 生成標準正態分布的隨機數。np.random.randint(): 生成指定范圍內的隨機整數。
使用注意事項
-
數組維度:確保在進行運算時,數組的維度和形狀是兼容的。使用
reshape()和expand_dims()可以幫助調整數組的形狀。 -
數據類型:NumPy 數組的元素類型是固定的,確保在創建數組時指定合適的數據類型(如
dtype),以避免意外的數據類型轉換。 -
內存管理:NumPy 數組通常比 Python 列表占用更少的內存,但在處理非常大的數組時,仍需注意內存使用情況。使用
np.memmap()可以處理超出內存限制的數組。 -
廣播機制:NumPy 支持廣播(broadcasting),這允許不同形狀的數組進行運算。理解廣播規則可以幫助你更有效地進行數據處理。
-
避免循環:盡量避免使用 Python 的 for 循環來處理 NumPy 數組,使用向量化操作(如數組運算)可以顯著提高性能。
-
隨機數種子:在進行隨機數生成時,如果需要可重復的結果,可以使用
np.random.seed()設置隨機數種子。 -
使用文檔:NumPy 有豐富的文檔和示例,遇到問題時可以參考官方文檔(NumPy Documentation)。
知識點
NumPy 是 Python 數據科學和機器學習領域中的核心庫之一,因此它經常成為面試中的話題。以下是一些關于 NumPy 的高頻面試題目以及相應的答案:
NumPy 中的 ndarray 是什么?
ndarray 是 NumPy 中的一個核心對象,用于存儲同質類型的元素(如整數、浮點數等)。它是一個多維數組,可以進行高效的元素級操作。
如何創建一個形狀為 (3, 4) 的 NumPy 數組,并且用 0 填充?
答案:
import numpy as np
array = np.zeros((3, 4))
這將創建一個 3 行 4 列的數組,所有元素都是 0。
如何獲取 NumPy 數組的形狀?
import numpy as np
array = np.array([[1, 2, 3], [4, 5, 6]])
shape = array.shape
shape 屬性會返回一個元組,表示數組的形狀。
如何改變 NumPy 數組的形狀而不改變其數據?
import numpy as np
array = np.array([[1, 2, 3], [4, 5, 6]])
reshaped_array = array.reshape(3, 2)
這將把原數組改變為 3 行 2 列的形狀。
如何將 Python 列表轉換為 NumPy 數組?
使用 np.array() 函數可以將 Python 列表轉換為 NumPy 數組。
如何計算 NumPy 數組的均值、標準差和方差?
分別使用 np.mean()、np.std() 和 np.var() 函數。例如均值計算如下:
import numpy as np
array = np.array([1, 2, 3, 4, 5])
mean_value = np.mean(array)
np.mean() 函數可以計算數組的均值。
如何在 NumPy 數組中進行元素級別的操作?
NumPy 支持元素級別的操作,這意味著你可以對數組中的每個元素應用算術運算或其他函數。例如:
import numpy as np
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
added_array = array1 + array2
這將返回一個新數組 [5, 7, 9]。
如何使用 NumPy 生成隨機數?
import numpy as np
random_array = np.random.rand(3, 4)
np.random.rand() 函數可以生成一個給定形狀的數組,其元素是從 [0, 1) 區間內均勻分布的隨機數。
如何檢查一個 NumPy 數組是否包含任何 NaN 值?
import numpy as np
array = np.array([1, 2, np.nan, 4])
contains_nan = np.isnan(array)
np.isnan() 函數可以返回一個布爾數組,指示哪些位置是 NaN。
如何在 NumPy 數組中進行條件篩選?
import numpy as np
array = np.array([1, 2, 3, 4, 5])
filtered_array = array[array > 2]
這將返回一個新數組 [3, 4, 5],包含所有大于 2 的元素。
解釋 NumPy 中的 dtype。
在 NumPy 中,dtype 是一個非常重要的概念,它代表數據類型(Data Type)。每個 NumPy 數組都有一個與之相關的 dtype,它指定了數組中每個元素的數據類型。這有助于 NumPy 在內存中有效地存儲和處理數據。
dtype 的關鍵點
-
同質性:NumPy 數組是同質的,這意味著數組中的所有元素都必須是相同的數據類型。
dtype確保了這一點。 -
內存效率:通過指定
dtype,可以控制數組在內存中的存儲方式,從而提高內存使用效率。 -
操作優化:不同的數據類型可能會影響數組操作的性能。例如,整數和浮點數的操作速度可能不同。
-
類型轉換:如果創建數組時沒有指定
dtype,NumPy 會根據數組元素的類型自動推斷dtype。但是,如果需要,也可以顯式指定dtype。 -
類型安全:在執行數組操作時,確保所有元素的數據類型一致可以避免類型不匹配的錯誤。
常見的 NumPy 數據類型:
np.int32:32位整數np.int64:64位整數np.float32:32位浮點數np.float64:64位浮點數(雙精度)np.bool_:布爾類型(True 或 False)np.complex64:復數,實部和虛部各占32位np.complex128:復數,實部和虛部各占64位np.object:Python 對象np.string_:字符串類型np.datetime64:日期時間類型
示例
創建一個具有特定 dtype 的 NumPy 數組:
import numpy as np
# 創建一個整數類型的數組
int_array = np.array([1, 2, 3], dtype=np.int32)
print(int_array.dtype) # 輸出:int32
# 創建一個浮點數類型的數組
float_array = np.array([1.0, 2.0, 3.0], dtype=np.float64)
print(float_array.dtype) # 輸出:float64
# 創建一個布爾類型的數組
bool_array = np.array([True, False, True], dtype=bool)
print(bool_array.dtype) # 輸出:bool
注意事項
- 當執行數組操作時,如果涉及不同
dtype的數組,NumPy 通常會執行類型提升(type casting),以確保結果數組的數據類型能夠容納所有可能的值。 - 顯式指定
dtype可以幫助避免不必要的類型轉換,從而提高代碼的性能和可讀性。 - 在處理大數據集時,合理選擇
dtype可以顯著減少內存使用,提高處理速度。
dtype 是 NumPy 數組的一個重要屬性,了解和正確使用 dtype 對于進行高效的數值計算至關重要。
為什么 NumPy 比 Python 原生列表更快?
-
數據存儲:
- NumPy 數組在內存中以連續塊的形式存儲數據,這意味著數組中的元素是緊密排列的。這種連續存儲方式使得 CPU 緩存能夠更有效地工作,因為當訪問數組中的一個元素時,相鄰的元素也會被加載到緩存中。
- Python 原生列表存儲的是對象的引用,這些對象可能散布在內存的任何地方,這導致了更多的內存訪問延遲。
-
數據類型:
- NumPy 數組中的元素都是同質的,這意味著它們具有相同的數據類型,這使得 NumPy 可以優化內存使用和計算操作。
- Python 列表可以包含不同類型的元素,這增加了內存使用的復雜性。
-
操作優化:
- NumPy 是用 C 語言編寫的,它的數組操作是用低級語言實現的,這使得操作非常快速和高效。
- Python 列表的操作是用 Python 這門高級語言實現的,這通常涉及到更多的函數調用和解釋器開銷。
-
向量化操作:
- NumPy 支持向量化操作,這意味著可以一次性對數組的多個元素執行操作,而不需要使用循環。這些操作是用 C 語言編寫的,可以被編譯成機器代碼,從而實現高性能。
- Python 列表通常需要使用循環來迭代元素,這增加了額外的開銷。
-
廣播機制:
- NumPy 的廣播機制允許不同形狀的數組在算術操作中協同工作,而不需要顯式地進行元素級別的循環。
-
算法實現:
- NumPy 的算法實現通常更加優化,因為它們是專門為數值計算設計的。
-
并行處理:
- 對于某些操作,NumPy 可以利用并行處理來進一步提高性能,尤其是在多核處理器上。
-
內存管理:
- NumPy 在創建數組時,會明確指定數據類型和大小,這有助于減少內存分配和回收的開銷。
-
緩存效率:
- 由于 NumPy 數組的連續內存分配,現代 CPU 的緩存機制能夠更有效地工作,因為數據訪問模式更加局部化。
-
避免Python解釋器開銷:
- Python 列表的操作需要 Python 解釋器的介入,而 NumPy 操作很多都是直接在底層執行,避免了解釋器的開銷。
如何優化 NumPy 代碼的性能?
答案:使用向量化操作而不是循環,避免不必要地復制數據,使用適當的數據類型,以及并行處理(如使用 np.dot 替代 for 循環計算點積)。
解釋 NumPy 中的廣播機制。
NumPy 中的廣播(Broadcasting)機制是一種強大的功能,它允許不同形狀的數組在數學運算中協同工作,而不需要顯式地匹配它們的形狀。廣播機制遵循以下規則:
-
維度對齊:從左到右比較兩個數組的維度,確保它們的維度是對齊的。這意味著較短數組的前面會填充1(例如,
(3,)被視為(1, 3))。 -
維度擴展:如果兩個數組在某個維度的大小不一致,那么較小數組的形狀會在該維度上被擴展以匹配較大數組。這是通過復制較小數組的維度值來實現的。
-
形狀比較:從尾部維度(最右邊的維度)開始,逐個維度比較兩個數組的形狀。如果兩個維度相等,或其中一個維度為1,則認為它們是兼容的。
-
復制擴展:如果一個數組的維度大小為1,而另一個數組的維度大小大于1,則將維度大小為1的數組復制擴展到與另一個數組相同的維度大小。
-
廣播結果:如果兩個數組在所有維度上都兼容,那么它們就可以進行廣播,從而形成一個新的數組形狀,用于計算。
例如:
import numpy as np
# 創建兩個數組
a = np.array([1, 2, 3]) # 形狀為 (3,)
b = np.array([[1], [2], [3]]) # 形狀為 (3, 1)
# 廣播相加
c = a + b # 結果是一個形狀為 (3, 3) 的數組
print(c)
# 輸出:
# [[2 2 2]
# [3 3 3]
# [4 4 4]]
在這個例子中,a 的形狀是 (3,),b 的形狀是 (3, 1)。根據廣播規則,a 被擴展到 (3, 3),b 也被擴展到 (3, 3),然后進行逐元素相加。
廣播機制使得 NumPy 在執行元素級操作時非常高效,因為它避免了不必要的數組復制和循環。然而,它也有潛在的缺點,比如有時可能會導致意外的結果,特別是在數組形狀復雜或操作不明確時。因此,理解廣播機制對于編寫清晰、高效的 NumPy 代碼至關重要。
在機器學習中,如何使用 NumPy 進行特征縮放?
在機器學習中,特征縮放是一種重要的預處理步驟,它有助于改善模型的性能和收斂速度。特征縮放包括多種技術,其中最常見的是最小-最大歸一化(Min-Max Scaling)和標準化(Standardization)。以下是如何使用 NumPy 進行這兩種特征縮放的方法:
最小-最大歸一化(Min-Max Scaling)
最小-最大歸一化將特征縮放到一個指定的范圍,通常是 [0, 1]。這種方法對于保持數據中的特征比例很有用。
import numpy as np
# 假設 X 是一個形狀為 (n_samples, n_features) 的數據數組
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 計算每個特征的最小值和最大值
X_min = X.min(axis=0)
X_max = X.max(axis=0)
# 執行最小-最大歸一化
X_scaled = (X - X_min) / (X_max - X_min)
print(X_scaled)
標準化(Standardization)
標準化(也稱為 Z-score 歸一化)將特征縮放,使得它們的均值為 0,標準差為 1。這有助于確保不同特征的尺度不會影響模型的優化過程。
# 假設 X 是一個形狀為 (n_samples, n_features) 的數據數組
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 計算每個特征的均值和標準差
X_mean = X.mean(axis=0)
X_std = X.std(axis=0)
# 執行標準化
X_standardized = (X - X_mean) / X_std
print(X_standardized)
注意事項
-
避免數據泄露:在訓練集上計算用于縮放的參數(如最小值、最大值、均值和標準差)時,應確保不要使用測試集或驗證集的數據,這被稱為數據泄露。
-
保存縮放參數:在訓練集上訓練模型后,應該保存用于特征縮放的參數(最小值、最大值、均值和標準差),以便在測試集或生產環境中對新數據進行相同的縮放。
-
選擇縮放方法:不同的模型可能對特征縮放的敏感度不同。例如,距離基模型(如 K-最近鄰和 SVM)通常會從縮放中受益,而樹基模型(如決策樹和隨機森林)通常不需要特征縮放。
-
處理缺失值:在進行特征縮放之前,應該處理數據中的缺失值,因為它們可能會影響均值和標準差的計算。
使用 NumPy 進行特征縮放是直接且高效的,但請注意,NumPy 不提供內置的函數來自動應用這些縮放技術。在實踐中,scikit-learn 庫提供了更高級的特征縮放方法,如 MinMaxScaler 和 StandardScaler,它們可以更方便地處理這些問題。
如何使用 NumPy 進行主成分分析(PCA)?
步驟 1: 準備數據
首先,你需要一個形狀為 (n_samples, n_features) 的數據數組。
import numpy as np
# 示例數據
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
步驟 2: 數據標準化
PCA 對數據的尺度非常敏感,因此通常需要先標準化數據。
X_centered = X - np.mean(X, axis=0)
X_std = np.std(X_centered, axis=0)
X_normalized = X_centered / X_std
步驟 3: 計算協方差矩陣
協方差矩陣用于找到數據的主成分。
cov_matrix = np.cov(X_normalized.T)
步驟 4: 計算特征值和特征向量
特征值和特征向量表示了數據的主成分方向。
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
步驟 5: 選擇主成分
選擇最大的幾個特征值對應的特征向量作為主成分。
# 按特征值大小降序排序特征向量
sorted_index = np.argsort(eigenvalues)[::-1]
principal_components = eigenvectors[:, sorted_index[:n_components]]
其中 n_components 是你想要保留的成分數量。
步驟 6: 轉換數據
將原始數據投影到選定的主成分上。
X_pca = np.dot(X_normalized, principal_components)
使用 X_pca 可以得到降維后的數據。
NumPy PCA 示例代碼
import numpy as np
# 示例數據
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 標準化數據
X_centered = X - np.mean(X, axis=0)
X_std = np.std(X_centered, axis=0)
X_normalized = X_centered / X_std
# 計算協方差矩陣
cov_matrix = np.cov(X_normalized.T)
# 計算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
# 按特征值大小降序排序特征向量
sorted_index = np.argsort(eigenvalues)[::-1]
n_components = 2 # 選擇前兩個主成分
principal_components = eigenvectors[:, sorted_index[:n_components]]
# 轉換數據
X_pca = np.dot(X_normalized, principal_components)
print(X_pca)
注意事項
- 數據標準化是 PCA 的重要步驟,確保每個特征具有單位方差。
- 在實踐中,通常使用
scikit-learn的 PCA 實現,因為它更高效、更方便,并且包含了更多的功能,如自動選擇組件數量等。 - NumPy 的 PCA 實現沒有考慮奇異值分解(SVD),這在處理具有更多特征的數據時可能更有效。
使用 scikit-learn 的 PCA 實現非常簡單:
from sklearn.decomposition import PCA
# 示例數據
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 初始化 PCA,n_components 為需要保留的成分數量
pca = PCA(n_components=2)
# 對數據進行擬合和轉換
X_pca = pca.fit_transform(X)
print(X_pca)
這種方法更加簡潔,且 scikit-learn 會自動處理數據標準化和奇異值分解(SVD)。

浙公網安備 33010602011771號