機器學習入門系列①|為機器學習索引、切片和重塑NumPy數組
如果你是Python新手,可能會對一些Python式的數據訪問方式感到困惑,例如負索引和數組切片。本教程將帶了解如何在NumPy數組中正確操作和訪問數據。(如有錯漏請大家指正)
完成本教程后,你可以掌握:1、如何將列表數據轉換為NumPy數組;2、如何使用Pythonic索引和切片訪問數據;3、如何調整數據大小以滿足某些機器學習API的期望等知識點。
本教程分為4部分:
從列表到數組
數組索引
數組切片
數組重塑
廢話不多說,搬好小板凳,拿好筆記本,開始認真學習!

1. 從列表到數組
一般來說,建議使用Pandas甚至NumPy函數從文件加載數據。
先來學習如何在Python中加載機器學習數據
機器學習數據最常見的格式是CSV文件。有多種方法可以在Python中加載CSV文件。這里給大家簡單介紹幾種在Python中加載機器學習數據的不同方法。
加載 CSV 數據時的注意事項
從 CSV 文件加載機器學習數據時有許多注意事項。
可以參考這個文檔內容:
https://tools.ietf.org/html/rfc4180
CSV文件標題
你的數據有文件頭嗎?如果有,這有助于自動為每列數據分配名稱。如果沒有,需要手動命名文件頭。
無論哪種方式,都應該在加載數據時明確指定CSV文件是否具有文件頭。
注釋
CSV文件中的注釋由行首的散列 (“#”) 表示。
如果文件中有注釋,根據用于加載數據的方法,需要指明是否需要注釋以及需要表示注釋行的字符。
分隔符
在字段中分隔值的標準分隔符是逗號 (“,”) 字符。
文件可以使用不同的分隔符,如制表符 (“\t”),在這種情況下,必須明確指定它。
引號
有時字段值可以有空格。在這些CSV文件中,經常引用這些值。
默認引號字符是雙引號“\”??梢允褂闷渌址?,并且您必須指定文件中使用的引號字符。
機器學習數據加載方法
每個方法都是獨立的。
所以可以將其復制并粘貼到別的項目中并立即使用。
使用Python標準庫加載CSV
Python API提供了模塊CSV和可用于加載CSV文件的函數reader()。
加載后,將CSV數據轉換為NumPy數組并將其用于機器學習。
可以將Pima Indians數據集下載到本地使用。
下載鏈接:
https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv
所有字段都是數字,沒有標題行。運行下面的方法將加載CSV文件并將其轉換為NumPy數組。
該示例加載了一個對象,該對象可以迭代數據的每一行,并且可以輕松地轉換為NumPy數組。運行示例print出數組的值。
有關csv.reader()函數的更多信息,請參閱Python API文檔中的CSV文件讀取和寫入(文檔見文章底部鏈接)。
使用NumPy加載CSV文件
可使用NumPy和numpy.loadtxt()函數加載CSV數據。
此函數假定沒有標題行并且所有數據都具有相同的格式。下面的示例假設文pima-indians-diabetes.data.csv位于當前的工作目錄中。
運行該示例會將文件加載為numpy.ndarray并print數據的值(形狀):
可以修改此示例以直接從URL加載相同的數據集,如下所示:
注意:示例使用的是Python3。
同樣,運行該示例會生成相同的數據結果值。
有關numpy.loadtxt()函數的更多信息,請參閱API文檔(numpy的1.10版?zhèn)魉烷T見文章底部)。
使用Pandas加載CSV文件
可以使用Pandas和pandas.read_csv()函數加載CSV數據。
這個函數非常靈活,也許是我推薦的加載機器學習數據的方法。該函數返回一個pandas.DataFrame,您可以立即開始匯總和繪圖。
下面的示例假設“pima-indians-diabetes.data.csv ”文件位于當前工作目錄中。
請注意,在此示例中,我們明確指定了DataFrame的每個屬性的名稱。運行示例顯示數據的值(形狀):
我們還可以修改此示例以直接從URL加載CSV數據。
同樣,運行該示例會下載CSV文件,對其進行解析并顯示加載的DataFrame的形狀。
要了解有關pandas.read_csv()函數的更多信息,參考API文檔(文檔傳送門在文章底部)。
掌握以上鍵入并粘貼的方法,熟悉在Python中加載機器學習數據的不同方式,接下來讓我們繼續(xù)學習將列表中的數據轉換為NumPy數組。

一維列表轉數組
加載數據或生成數據以列表的形式訪問。
通過調用NumPy函數array()將一維數據列表轉換為數組。
運行該示例會將一維列表轉換為NumPy數組。
Two-Dimensional List of Lists to Array
在機器學習中,我們會碰到二維數據。
一個數據表,其中每一行代表一個new observation,每一列代表一個new feature。
通過生成數據或使用自定義代碼加載它,現(xiàn)在您有了一個列表的列表(list of lists)。每個列表代表一個新的觀察結果。
通過調用array()函數,以與上述相同的方式將列表的列表轉換為NumPy數組。(感覺自己在說繞口令)
運行示例顯示數據已成功轉換。
2. 數組索引
一旦使用NumPy數組表示數據,就可以使用索引訪問它。
來看通過索引訪問數據的示例:
一維索引
通常,索引的工作方式與其他編程語言(如Java、C#和C++)的經驗一樣。
我們可以使用方括號[ ]運算符訪問元素,指定要檢索的值的零偏移索引。
運行該示例將打印數組中的第一個和最后一個值。
為數組邊界指定太大的整數會導致錯誤。
運行該示例會打印以下錯誤:
這里可以使用負索引來檢索從數組末尾偏移的值。
例如,索引-1指的是數組中的最后一項。對于當前示例中的第一項,索引-2將返回倒數第二項,一直返回到-5。
運行該示例將打印數組中的最后一項和第一項。
二維索引
索引二維數據與索引一維數據類似,只是用逗號分隔每個維度的索引。
例如,我們可以按如下方式訪問第一行和第一列:
運行該示例將打印數據集中的第一項。
如果對第一行中的所有項感興趣,可以將第二個維度索引留空,例如:
這將打印第一行數據。
3. 數組切片
數組切片是對Python和NumPy數組的初學者造成問題的一個知識點。
可以對列表和NumPy數組等結構進行切片。這意味著可以索引和檢索結構的子序列。
當指定輸入變量和輸出變量或從測試行中拆分訓練行時,數組切片就會在機器學習中成為最有用的。
切片是使用冒號運算符 ':' 指定的,在列之前和之后分別帶有 ' from ' 和 ' to ' 索引。切片從 'from' 索引延伸并在 'to' 索引之前結束一項。
讓我們來看看一些例子:
一維切片
您可以通過指定不帶索引的切片 ':' 來訪問數組維度中的所有數據。
運行該示例將打印數組中的所有元素。
可以通過指定從索引0開始到索引1結束的切片('to' 索引之前的一項)來對數組的第一項進行切片。
運行該示例將返回一個包含第一個元素的子數組。
我們也可以在切片中使用負索引。例如,我們可以通過從 -2(倒數第二個項目)開始切片而不指定“to”索引來對列表中的最后兩個項目進行切片;將切片帶到維度的末尾。
運行該示例將返回一個僅包含最后兩項的子數組。
二維切片
讓我們看一下最有可能在機器學習中使用的二維切片的兩個示例。
拆分輸入和輸出功能
通常將加載的數據拆分為輸入變量 (X) 和輸出變量 (y)。
我們可以通過切片所有行和所有列來做到這一點,但在最后一列之前,然后單獨索引最后一列。
對于輸入特征,我們可以通過?':'?在行索引中指定,:-1在列索引中指定,選擇除最后一行之外的所有行和所有列。
對于輸出列,我們可以使用 ':' 再次選擇所有行,并通過-1指定索引來索引最后一列。
將所有這些放在一起,我們可以將一個3列的2D數據集分成輸入和輸出數據,如下所示:
運行示例打印分離的X和y元素。請注意,X是一個二維組,而y是一個一維數組。
拆分訓練和測試行
將加載的數據集拆分為單獨的訓練集和測試集是很常見的。
這是行的拆分,其中一些部分將用于訓練模型,其余部分將用于估計訓練模型的技能。
這將涉及通過在第二個維度索引中':'來指定對所有列進行切片。訓練數據集將是從開始到分割點的所有行。
測試數據集將是從分割點開始到維度末尾的所有行。
將所有這些放在一起,我們可以在人為的指定2個分割點來分割數據集。
運行示例選擇前兩行進行訓練,最后一行選擇測試集。
4. 數組整形
對數據進行切片后,需要對其進行整形。
例如,一些庫,例如scikit-learn,可能需要將輸出變量 (y) 的一維數組成形為二維數組,其中包含一列和每行的結果。
一些算法,如Keras中的Long Short-Term Memory循環(huán)神經網絡,需要將輸入指定為由樣本、時間步長和特征組成的三維數組。
重要的是要知道如何重塑NumPy數組,以便數據滿足特定 Python庫的需求??聪旅孢@兩個例子。
數據形狀
NumPy數組有一個shape屬性,該屬性返回數組每個維度長度的元組。
例如:
運行示例打印一維的元組。
為二維數組返回具有兩個長度的元組。
運行該示例將返回一個包含行數和列數的元組。
還可以在形狀維度中使用數組維度的大小,例如指定參數。
元組的元素可以像數組一樣訪問,第0個索引表示行數,第1個索引表示列數。例如:
運行示例訪問每個維度的特定大小。
將一維數組重塑為二維數組
通常需要將一維數組重塑為一列多行的二維數組。
NumPy在NumPy數組對象上提供了reshape()函數,可用于對數據進行整形。
reshape()函數采用一個參數來指定數組的新形狀。在將一維數組重塑為具有一列的二維數組的情況下,元組將是數組的形狀作為第一維 (data.shape[0]) 和1作為第二維。
將所有這些放在一起,看示例:
運行該示例打印一維數組的形狀,將數組重塑為5行和1列,然后打印這個新形狀。
重塑2D到3D陣列
對于需要一個或多個時間步長和一個或多個特征的多個樣本的算法,通常需要將其中每一行代表一個序列的二維數據重塑為一個三維數組。
一個很好的例子是Keras深度學習庫中的LSTM循環(huán)神經網絡模型(參考文檔在文章底部)。
reshape()函數可以直接使用,指定新的維度。這在一個例子中很明顯,其中每個序列都有多個時間步,每個時間步都有一個觀察(特征)。
我們可以使用數組上shape屬性中的大小來指定樣本(行)和列(時間步長)的數量,并將特征數量固定為 1。
將所有這些放在一起,來看示例:
運行示例首先打印2D數組中每個維度的大小,重新調整數組的形狀,然后總結新3D數組的形狀。
終于寫完了!你們看懂了嗎?跟著敲敲代碼吧!里面有一些涉及的知識點文檔鏈接,學姐也放在下面了。
本文整理自:
https://machinelearningmastery.com/index-slice-reshape-numpy-arrays-machine-learning-python/
https://machinelearningmastery.com/load-machine-learning-data-python/
(本文來源于網絡,如有侵權請聯(lián)系刪除。可通過鏈接訪問原文參與討論)
LSTM循環(huán)神經網絡模型:
https://keras.io/layers/recurrent/#lstm
Python API文檔:
https://docs.python.org/2/library/csv.html
