譯文:如何為機器學習索引,切片,調整 NumPy 數組
原文鏈接:https://machinelearningmastery.com/index-slice-reshape-numpy-arrays-machine-learning-python/
原文作者:Jason Brownlee
在機器學習中,數據被表示為數組。
具體在 Python 中,數據幾乎被都被表示為 NumPy 數組。
如果你剛從小夥伴那裡了解到 Python,可能會對一些訪問數據的方式困惑,例如負數索引和數組切片等等一些pythonic的操作。
在本教程中,你將了解如何正確地操作和訪問NumPy數組中的數據。
完成本教程後,你獲得以下這些技能:
- 如何將你的列表數據轉換為NumPy數組。
- 如何使用Pythonic索引和切片操作訪問數據。
- 如何調整數據維數以滿足某些機器學習API的輸入參數的維數要求。
現在就讓我們開始吧。
教程概述
本教程分為 4 個部分:
- 從列表到數組
- 數組索引
- 數組切片
- 數組維數調整
1.從列表到數組
一般來說,我建議使用 Pandas 甚至使用 NumPy 的函數從文件載入數據。
有關示例,請參閱筆者以前的文章:
- 如何在Python中載入機器學習數據
本節假定你已經通過不同於上述兩種的其他方式載入或生成了你的數據,現在正使用 Python 列表來存儲這些數據。
我們來看看如何將這些列表中的數據轉換為 NumPy 數組。
一維列錶轉換為數組
你可以通過一個列表來載入或者生成,存儲並操作你的數據。
本節中,你可以通過調用 array( )這個 NumPy 函數將一維數據列錶轉換為數組。如下所示:
# one dimensional examplefrom numpy import array# list of datadata = [11, 22, 33, 44, 55]# array of datadata = array(data)print(data)print(type(data))
運行該示例將一維列錶轉換為 NumPy 數組。
[11 22 33 44 55]<class numpy.ndarray>
二維列錶轉換為數組
在機器學習中,更有可能產生或需要二維數據。
假設有一個數據表,其中每一行代表一個觀察點,每一列代表一個不同屬性。
也許你生成了這些數據,或者使用自己的代碼載入了這個數據表,現在你有一個二維列表(列表中的每一項是一個列表)。每個列表代表一個新的觀察點。
還是可以通過調用 array( )函數將二維列錶轉換為NumPy數組。
# two dimensional examplefrom numpy import array# list of datadata = [[11, 22],[33, 44],[55, 66]]# array of datadata = array(data)print(data)print(type(data))
運行示例顯示成功轉換的數據。
[[11 22][33 44][55 66]]<class numpy.ndarray>
2.數組索引
一旦你的數據使用 NumPy 數組進行表示,就可以使用索引訪問其中的數據。
我們來看一些通過索引訪問數據的例子。
一維數組的索引
一般來說,NumPy 中索引的工作方式與使用其他編程語言(如 Java,C# 和 C ++)時的經驗類似。
例如,可以使用括弧運算符[]指定要檢索的數據序號(從零開始的偏移量)來訪問元素。
# simple indexingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])# index dataprint(data[0])print(data[4])
運行示例列印數組中的第一個和最後一個值。
1155
指定過大的,超出數組邊界的整數將導致數組越界錯誤。
# simple indexingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])# index dataprint(data[5])
運行該示例將輸出以下錯誤:
IndexError: index 5 is out of bounds for axis 0 with size 5
但 Python 的索引同其他編程語言有一個關鍵的區別是,你可以使用負索引來從數組尾部檢索值。
例如,索引 -1 代表數組中的最後一項。索引 -2 代表數組中的倒數第二項,示例中的 -5 索引代表數組中的第一個值(因為數組中只有 5 個數)。
# simple indexingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])# index dataprint(data[-1])print(data[-5])
運行該示例將列印數組中的最後一項和第一項。
5511
二維數組的索引
二維數組的索引與一維數組類似,區別在於用逗號分隔各個維度的索引。
data[0,0]
這與基於C語言的編程語言不同,其每個維度使用單獨的中括弧運算符。
data[0][0]
例如,我們通過以下程序可以訪問數組的第一行中的第一列,如下所示:
# 2d indexingfrom numpy import array# define arraydata = array([[11, 22], [33, 44], [55, 66]])# index dataprint(data[0,0])
運行該示例將列印數據集中的第一個數字。
11
如果我們對第一行中的所有項感興趣,可以將第二維索引留空,例如:
# 2d indexingfrom numpy import array# define arraydata = array([[11, 22], [33, 44], [55, 66]])# index dataprint(data[0,])
這將列印第一行的數據。
[11 22]
3.數組切片
文章到現在為止似乎還挺容易; 創建數組和建立索引感覺很熟悉。
現在我們來到數組切片的部分,這部分往往是初學者面對 Python 和 NumPy 時經常產生疑問的地方。
列表和 NumPy 數組等數據結構可以進行切片操作。意味著這些數據結構的子序列可以通過切片被索引和獲取。
在指定輸入,輸出變數,或從測試集所在行中提取訓練數據行,這些機器學習經常用到的操作時,切片無疑是非常好用的。
切片使用冒號運算符: 冒號之前之後的索引值分別代表「 from 」和「 to 」。切片從「from」索引開始,並在「to」索引之前結束。(切片操作的範圍包含起始項,但不包含結束項)
data[from:to]
讓我們通過一些例子來說明切片的用法。
一維切片
可以通過將索引留空,使用「:」來訪問數組該維度中的所有數據。
# simple slicingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])print(data[:])
運行該示例將列印數組中的所有元素。
[11 22 33 44 55]
數組的第一項可以通過指定從索引 0 開始到索引 1 結束的切片(即在『 1 』之前結束)來獲取。
# simple slicingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])print(data[0:1])
運行該示例返回一個包含第一個元素的子數組。
[11]
我們也可以在切片中使用負數索引。例如,我們可以通過切片獲得列表中的最後兩項,將切片的起始位設為 -2 ,將結束位留空。這樣,切片就從列表的倒數第二項開始,到列表最後結束。
# simple slicingfrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])print(data[-2:])
運行該示例返回僅包括最後兩項的子數組。
[44 55]
二維切片
我們來看看你最有可能在機器學習中使用的兩個二維切片的例子。
拆分輸入輸出
將載入的數據分解為輸入變數(X)和輸出變數(y)在機器學習中是很常見的操作。
我們可以通過切片得到不包括最後一列的所有數據行,然後單獨索引最後一列來實現輸入輸出變數的分離。
具體來說,對於輸入數據,我們可以通過在行索引中使用:,列索引中指定 『:-1』來選取不包括最後一列的所有數據行。
X = [:, :-1]
對於代表輸出的最後一列,我們可以在行索引中使用:再次選擇所有行,並通過在列索引中指定『-1』索引來選取所有數據行的最後一列。
y = [:, -1]
將兩項操作整合,我們可以把列數為 3 的二維數據集分離成輸入和輸出數據,如下:
# split input and outputfrom numpy import array# define arraydata = array([[11, 22, 33],[44, 55, 66],[77, 88, 99]])# separate dataX, y = data[:, :-1], data[:, -1]print(X)print(y)
運行該示例列印分離的X和Y元素。請注意,X是二維數組,y是一維數組。
[[11 22][44 55][77 88]][33 66 99]
拆分訓練行和測試行
將載入的數據集分成單獨的訓練集和測試集也是很常見的操作。
這是一個行切片操作,數據中一部分用於訓練模型,其餘部分將用於估計訓練模型的效果。
操作涉及通過在列索引中指定「:」來獲取所有列。訓練數據集包括從開始一直到分隔行的所有數據行(不包含分隔行)。
datasettrain = data[:split, :]
測試數據集將是從分隔行開始到結束的所有行。
test = data[split:, :]
通過上述兩項操作,我們可以在設置的分隔行,將數據集分為兩部分。
# split train and testfrom numpy import array# define arraydata = array([[11, 22, 33],[44, 55, 66],[77, 88, 99]])# separate datasplit = 2train,test = data[:split,:],data[split:,:]print(train)print(test)
運行示例將前兩行選為訓練集,最後一行作為測試集。
[[11 22 33][44 55 66]][[77 88 99]]
4.數列維數變形
對數據切片之後,你可能還需要對現有的數據進行維度變形。
例如,一些庫(如 scikit-learn)可能需要將輸出變數(y)的一維數組變形為二維數組,在每列的基礎上增加該列的結果。
一些演算法,如 Keras 中的長短期記憶遞歸神經網路,將輸入數據指定為由採樣值,時間步長和特徵組成的三維數組。
明白如何變形 NumPy 數組,以便數據滿足特定 Python 庫的輸入需求,是非常重要的。我們來看看以下兩個例子。
數據形狀
NumPy 數組有一個 shape 屬性,它返回一個包含數組每個維度中數據數量的元組。
例如:
# array shapefrom numpy import array# define arraydata = array([11, 22, 33, 44, 55])print(data.shape)
運行該示例將列印一個一維元組。
(5,)
二維數組的返回值將是一個二維元組。
# array shapefrom numpy import array# list of datadata = [[11, 22],[33, 44],[55, 66]]# array of datadata = array(data)print(data.shape)
運行該示例將返回一個包括數組行數和列數的元組。
(3, 2)
可以通過訪問這個元組得到數組維度的大小,例如訪問元組的第 n 個索引。
元組的元素可以像數組一樣被訪問,上述元組中,第 0 個索引對應數組的行數,第 1 個索引對應列數。例如
# array shapefrom numpy import array# list of datadata = [[11, 22],[33, 44],[55, 66]]# array of datadata = array(data)print(Rows: %d % data.shape[0])print(Cols: %d % data.shape[1])
運行示例將得到每個維度的數據個數。
Rows: 3Cols: 2
將一維數組轉換為二維數組
將一維數組調整為多行一列的二維數組是很常見的操作。
NumPy 為 NumPy 數組對象提供 reshape()函數,可用於調整維數。
reshape()函數接受一個指定數組新形狀的參數。在將一維數組重新整形為具有多行一列的二維數組的情況下,作為參數的元組,從 shape[0] 屬性中獲取行數,並將列數設定為1。
data = data.reshape((data.shape[0], 1))
同其他代碼整合後,我們得到以下的例子。
# reshape 1D arrayfrom numpy import arrayfrom numpy import reshape# define arraydata = array([11, 22, 33, 44, 55])print(data.shape)# reshapedata = data.reshape((data.shape[0], 1))print(data.shape)
運行該示例將列印一維數組的形狀,將數組重新整形為具有1列5行的數組,然後列印出新的維數。
(5,)(5, 1)
將2維數組轉化為3維數組
對於需要一個或多個時間步長以及特徵的多樣本的演算法,通常需要將每行代表序列的二維數組調整為三維數組。
一個很好的例子就是 Keras 深度學習庫中的 LSTM 遞歸神經網路模型。
reshape( ) 函數可以直接使用,指定新的維度。以下是一個清楚的例子,其中每個序列擁有多個步長,每個步長對應其相應的觀察結果。
我們可以使用數組的 shape 屬性中的維數大小來指定樣本(行)和列(時間步長)的數量,並將觀察結果的數量固定為1。
data.reshape((data.shape[0], data.shape[1], 1))
同其他代碼整合後,我們得到以下的例子。
# reshape 2D arrayfrom numpy import array# list of datadata = [[11, 22],[33, 44],[55, 66]]# array of datadata = array(data)print(data.shape)# reshapedata = data.reshape((data.shape[0], data.shape[1], 1))print(data.shape)
首先運行示例,列印 2 維數組中每個維度的大小,重新調整數組,然後列印新的 3 維數組的形狀。
(3, 2)(3, 2, 1)
拓展閱讀
這部分提供有關本文主題的更多內容,如果有興趣的話可以參閱.
- An Informal Introduction to Python
- Array Creation in NumPy API
- Indexing and Slicing in NumPy API
- Basic Indexing in NumPy API
- NumPy shape attribute
- NumPy reshape() function
概要
在本教程中,你了解了如何使用 Python 訪問 NumPy 數組中的數據,以及如何調整數組的維數。
具體來說,你了解到:
- 如何將您的列表數據轉換為 NumPy 數組。
- 如何使用 Pythonic 索引和切片訪問數據。
- 如何調整數組維數大小以滿足某些機器學習 API 的輸入要求。
以 Sepmer Fi 的昵稱發佈於雲+社區翻譯社
推薦閱讀:
※Python 數據分析隨筆 - numpy
※ImagePy教程 —— 擴展功能
※Python——numpy文件存取
※python與numpy使用的一些小tips(2)
※ImagePy教程 —— 選區運算