在我們使用Python語言進行機器學習程式設計的時候,這是一個非常常用的基礎函式庫。本文針對Python 機器學習庫 NumPy入門教程,有興趣的朋友一起學習吧
NumPy是一個Python語言的軟體包,它非常適合於科學計算。在我們使用Python語言進行機器學習程式設計的時候,這是一個非常常用的基礎函式庫。
本文是對它的一個入門教學。
介紹
NumPy是一個用於科技運算的基礎軟體包,它是Python語言實現的。它包含了:
強大的N維數組結構
#精密複雜的函數
- ##可整合到C/C 和Fortran程式碼的工具
- 線性代數,傅立葉變換以及隨機數能力
取得NumPy
#因為這是Python語言的軟體包,因此需要你的機器上首先需要具備Python語言的環境。關於這一點,請自行在網路上搜尋取得方法。
關於如何取得NumPy也請參考scipy.org官網上的Installing packages。本文不再贅述。
筆者建議使用pip的方式安裝Python包,指令如下:
#
pip3 install numpy
本文的程式碼如下的環境中驗證與測試:
- 硬體:MacBook Pro 2015
- OS:macOS High Sierra
- #語言環境:Python 3.6.2
- 軟體包:numpy 1.13.3
另外,
- 為了簡單起見,本文我們會透過Python的print函數來進行結果的驗證
- 為了拼字方便,我們會預設import numpy as np
基礎屬性與陣列創建
NumPy的基礎是一個同構的多維數據,數組中的元素可以透過下標來索引。在NumPy中,維度稱之為axis(複數是axes),維度的數量稱之為rank。
例如:
下面是一個具有rank 1的數組,axis的長度為3:
[1, 2, 3]
下面是一個有rank 2的陣列,axis的長度也是3:
[[ 1, 2, 3],
[ 4, 5, 6]]
#我們可以透過array函數來建立NumPy的數組,例如這樣:
#
a = np.array([1, 2, 3]) b = np.array([(1,2,3), (4,5,6)])
請注意,這裡方括號是必須的,下面這種寫法是錯誤的:
a = np.array(1,2,3,4) # WRONG!!!
#NumPy的陣列類別是ndarray,它有一個別名是numpy.array,但這與Python標準函式庫的array.array並不一樣。後者只是一個一維數組。而ndarray具有以下的屬性:
- ndarray.ndim:陣列的維數。在Python世界中,維度稱為rank
- ndarray.shape:陣列的維度。這是一系列數字,長度由數組的維度(ndim)決定。例如:長度為n的一維數組的shape是n。一個n行m列的矩陣的shape是n,m
- ndarray.size:陣列中所有元素的數量
- ndarray.dtype :數組中元素的類型,例如numpy.int32, numpy.int16或numpy.float64
- ndarray.itemsize:數組中每個元素的大小,單位為位元組
- ndarray.data:儲存陣列元素的緩衝。通常我們只需要透過下標來存取元素,而不需要存取緩衝
# create_array.py import numpy as np a = np.array([1, 2, 3]) b = np.array([(1,2,3), (4,5,6)]) print('a=') print(a) print("a's ndim {}".format(a.ndim)) print("a's shape {}".format(a.shape)) print("a's size {}".format(a.size)) print("a's dtype {}".format(a.dtype)) print("a's itemsize {}".format(a.itemsize)) print('') print('b=') print(b) print("b's ndim {}".format(b.ndim)) print("b's shape {}".format(b.shape)) print("b's size {}".format(b.size)) print("b's dtype {}".format(b.dtype)) print("b's itemsize {}".format(b.itemsize))
以下是這段程式碼的輸出:
#
a= [1 2 3] a's ndim 1 a's shape (3,) a's size 3 a's dtype int64 a's itemsize 8 b= [[1 2 3] [4 5 6]] b's ndim 2 b's shape (2, 3) b's size 6 b's dtype int64 b's itemsize 8
##我們也可以在建立陣列的時候,指定元素的類型,例如這樣:
c = np.array( [ [1,2], [3,4] ], dtype=complex )
特定array的創建
#在實際上的專案工程中,我們常常會需要一些特定的數據,NumPy中提供了這麼一些輔助函數:
zeros:用來創建元素全部是0的陣列
ones:用來創建元素全部是1的陣列
empty:用来创建未初始化的数据,因此是内容是不确定的
arange:通过指定范围和步长来创建数组
linespace:通过指定范围和元素数量来创建数组
random:用来生成随机数
# create_specific_array.py import numpy as np a = np.zeros((2,3)) print('np.zeros((2,3)= \n{}\n'.format(a)) b = np.ones((2,3)) print('np.ones((2,3))= \n{}\n'.format(b)) c = np.empty((2,3)) print('np.empty((2,3))= \n{}\n'.format(c)) d = np.arange(1, 2, 0.3) print('np.arange(1, 2, 0.3)= \n{}\n'.format(d)) e = np.linspace(1, 2, 7) print('np.linspace(1, 2, 7)= \n{}\n'.format(e)) f = np.random.random((2,3)) print('np.random.random((2,3))= \n{}\n'.format(f))
这段代码的输出如下
np.zeros((2,3)= [[ 0. 0. 0.] [ 0. 0. 0.]] np.ones((2,3))= [[ 1. 1. 1.] [ 1. 1. 1.]] np.empty((2,3))= [[ 1. 1. 1.] [ 1. 1. 1.]] np.arange(1, 2, 0.3)= [ 1. 1.3 1.6 1.9] np.linspace(1, 2, 7)= [ 1. 1.16666667 1.33333333 1.5 1.66666667 1.83333333 2. ] np.random.random((2,3))= [[ 0.5744616 0.58700653 0.59609648] [ 0.0417809 0.23810732 0.38372978]]
Shape与操作
除了生成数组之外,当我们已经持有某个数据之后,我们可能会需要根据已有数组来产生一些新的数据结构,这时候我们可以使用下面这些函数:
reshape:根据已有数组和指定的shape,生成一个新的数组
vstack:用来将多个数组在垂直(v代表vertical)方向拼接(数组的维度必须匹配)
hstack:用来将多个数组在水平(h代表horizontal)方向拼接(数组的维度必须匹配)
hsplit:用来将数组在水平方向拆分
vsplit:用来将数组在垂直方向拆分
下面我们通过一些例子来进行说明。
为了便于测试,我们先创建几个数据。这里我们创建了:
zero_line:一行包含3个0的数组
one_column:一列包含3个1的数组
a:一个2行3列的矩阵
b:[11, 20)区间的整数数组
# shape_manipulation.py zero_line = np.zeros((1,3)) one_column = np.ones((3,1)) print("zero_line = \n{}\n".format(zero_line)) print("one_column = \n{}\n".format(one_column)) a = np.array([(1,2,3), (4,5,6)]) b = np.arange(11, 20) print("a = \n{}\n".format(a)) print("b = \n{}\n".format(b))
通过输出我们可以看到它们的结构:
zero_line = [[ 0. 0. 0.]] one_column = [[ 1.] [ 1.] [ 1.]] a = [[1 2 3] [4 5 6]] b = [11 12 13 14 15 16 17 18 19]
数组b原先是一个一维数组,现在我们通过reshape方法将其调整成为一个3行3列的矩阵:
# shape_manipulation.py b = b.reshape(3, -1) print("b.reshape(3, -1) = \n{}\n".format(b))
这里的第二参数设为-1,表示根据实际情况自动决定。由于原先是9个元素的数组,因此调整后刚好是3X3的矩阵。这段代码输出如下:
b.reshape(3, -1) = [[11 12 13] [14 15 16] [17 18 19]]
接着,我们通过vstack函数,将三个数组在垂直方向拼接:
# shape_manipulation.py c = np.vstack((a, b, zero_line)) print("c = np.vstack((a,b, zero_line)) = \n{}\n".format(c))
这段代码输出如下,请读者仔细观察一下拼接前后的数据结构:
c = np.vstack((a,b, zero_line)) = [[ 1. 2. 3.] [ 4. 5. 6.] [ 11. 12. 13.] [ 14. 15. 16.] [ 17. 18. 19.] [ 0. 0. 0.]]
同样的,我们也可以通过hstack进行水平方向的拼接。为了可以拼接我们需要先将数组a调整一下结构:
# shape_manipulation.py a = a.reshape(3, 2) print("a.reshape(3, 2) = \n{}\n".format(a)) d = np.hstack((a, b, one_column)) print("d = np.hstack((a,b, one_column)) = \n{}\n".format(d))
这段代码输出如下,请再次仔细观察拼接前后的数据结构:
a.reshape(3, 2) = [[1 2] [3 4] [5 6]] d = np.hstack((a,b, one_column)) = [[ 1. 2. 11. 12. 13. 1.] [ 3. 4. 14. 15. 16. 1.] [ 5. 6. 17. 18. 19. 1.]]
请注意,如果两个数组的结构是不兼容的,拼接将无法完成。例如下面这行代码,它将无法执行:
# shape_manipulation.py # np.vstack((a,b)) # ValueError: dimensions not match
这是因为数组a具有两列,而数组b具有3列,所以它们无法拼接。
接下来我们再看一下拆分。首先,我们将数组d在水平方向拆分成3个数组。然后我们将中间一个(下标是1)数组打印出来:
# shape_manipulation.py e = np.hsplit(d, 3) # Split a into 3 print("e = np.hsplit(d, 3) = \n{}\n".format(e)) print("e[1] = \n{}\n".format(e[1]))
这段代码输出如下:
e = np.hsplit(d, 3) = [array([[ 1., 2.], [ 3., 4.], [ 5., 6.]]), array([[ 11., 12.], [ 14., 15.], [ 17., 18.]]), array([[ 13., 1.], [ 16., 1.], [ 19., 1.]])] e[1] = [[ 11. 12.] [ 14. 15.] [ 17. 18.]]
另外,假设我们设置的拆分数量使得原先的数组无法平均拆分,则操作会失败:
# np.hsplit(d, 4) # ValueError: array split does not result in an equal pision
除了指定数量平均拆分,我们也可以指定列数进行拆分。下面是将数组d从第1列和第3列两个地方进行拆分:
# shape_manipulation.py f = np.hsplit(d, (1, 3)) # # Split a after the 1st and the 3rd column print("f = np.hsplit(d, (1, 3)) = \n{}\n".format(f))
这段代码输出如下。数组d被拆分成了分别包含1,2,3列的三个数组:
f = np.hsplit(d, (1, 3)) = [array([[ 1.], [ 3.], [ 5.]]), array([[ 2., 11.], [ 4., 14.], [ 6., 17.]]), array([[ 12., 13., 1.], [ 15., 16., 1.], [ 18., 19., 1.]])]
最后我们再将数组d在垂直方向进行拆分。同样的,如果指定的拆分数无法平均拆分则会失败:
# shape_manipulation.py g = np.vsplit(d, 3) print("np.hsplit(d, 2) = \n{}\n".format(g)) # np.vsplit(d, 2) # ValueError: array split does not result in an equal pision np.vsplit(d, 3)将产生三个一维数组: np.vsplit(d, 3) = [array([[ 1., 2., 11., 12., 13., 1.]]), array([[ 3., 4., 14., 15., 16., 1.]]), array([[ 5., 6., 17., 18., 19., 1.]])]
索引
接下来我们看看如何访问NumPy数组中的数据。
同样的,为了测试方便,我们先创建一个一维数组。它的内容是 [100,200)区间的整数。
最基本的,我们可以通过array[index]的方式指定下标来访问数组的元素,这一点对于有一点编程经验的人来说应该都是很熟悉的。
# array_index.py import numpy as np base_data = np.arange(100, 200) print("base_data\n={}\n".format(base_data)) print("base_data[10] = {}\n".format(base_data[10]))
上面这段代码输出如下:
base_data =[100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199] base_data[10] = 110
在NumPy中,我们可以创建一个包含了若干个下标的数组来获取目标数组中的元素。如下所示:
# array_index.py every_five = np.arange(0, 100, 5) print("base_data[every_five] = \n{}\n".format( base_data[every_five]))
every_five是包含了我们要获取的下标的数组,它的内容大家应该很容易理解。我们可以直接通过方括号的形式来获取到所有我们指定了下标的元素,它们如下:
base_data[every_five] = [100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195]
下标数组可以是一维的,当然也可以是多维的。假设我们要获取一个2X2的矩阵,这个矩阵的内容来自于目标数组中1,2,10,20这四个下标的元素,则可以这样写:
# array_index.py a = np.array([(1,2), (10,20)]) print("a = \n{}\n".format(a)) print("base_data[a] = \n{}\n".format(base_data[a]))
这段代码输出如下:
a = [[ 1 2] [10 20]] base_data[a] = [[101 102] [110 120]]
上面我们看到的是目标数组是一维的情况,下面我们把这个数组转换成一个10X10的二维数组。
# array_index.py base_data2 = base_data.reshape(10, -1) print("base_data2 = np.reshape(base_data, (10, -1)) = \n{}\n".format(base_data2))
reshape函数前面已经介绍过,大家应该能够想到它的结果:
base_data2 = np.reshape(base_data, (10, -1)) = [[100 101 102 103 104 105 106 107 108 109] [110 111 112 113 114 115 116 117 118 119] [120 121 122 123 124 125 126 127 128 129] [130 131 132 133 134 135 136 137 138 139] [140 141 142 143 144 145 146 147 148 149] [150 151 152 153 154 155 156 157 158 159] [160 161 162 163 164 165 166 167 168 169] [170 171 172 173 174 175 176 177 178 179] [180 181 182 183 184 185 186 187 188 189] [190 191 192 193 194 195 196 197 198 199]]
对于二维数组来说:
假设我们只指定了一个下标,则访问的结果仍然是一个数组。
假设我们指定了两个下标,则访问得到的是其中的元素
我们也可以通过”-1”来指定“最后一个”的元素
# array_index.py print("base_data2[2] = \n{}\n".format(base_data2[2])) print("base_data2[2, 3] = \n{}\n".format(base_data2[2, 3])) print("base_data2[-1, -1] = \n{}\n".format(base_data2[-1, -1]))
这段代码输出如下。
对于更高维的数组,原理是一样的,读者可以自行推理。
base_data2[2] = [120 121 122 123 124 125 126 127 128 129] base_data2[2, 3] = 123 base_data2[-1, -1] = 199
除此之外,我们还可以通过”:“的形式来指定范围,例如:2:5 这样。只写”:“则表示全部范围。
请看下面这段代码:
# array_index.py print("base_data2[2, :]] = \n{}\n".format(base_data2[2, :])) print("base_data2[:, 3]] = \n{}\n".format(base_data2[:, 3])) print("base_data2[2:5, 2:4]] = \n{}\n".format(base_data2[2:5, 2:4]))
它的含义是:
获取下标为2的行的所有元素
获取下标为3的列的所有元素
获取下标为[2,5)行,下标为[2,4)列的所有元素。请读者仔细观察一下下面的输出结果:
base_data2[2, :]] = [120 121 122 123 124 125 126 127 128 129] base_data2[:, 3]] = [103 113 123 133 143 153 163 173 183 193] base_data2[2:5, 2:4]] = [[122 123] [132 133] [142 143]]
数学运算
NumPy中自然也少不了大量的数学运算函数,下面是一些例子,更多的函数请参见这里NumPy manual contents:
# operation.py import numpy as np base_data = (np.random.random((5, 5)) - 0.5) * 100 print("base_data = \n{}\n".format(base_data)) print("np.amin(base_data) = {}".format(np.amin(base_data))) print("np.amax(base_data) = {}".format(np.amax(base_data))) print("np.average(base_data) = {}".format(np.average(base_data))) print("np.sum(base_data) = {}".format(np.sum(base_data))) print("np.sin(base_data) = \n{}".format(np.sin(base_data)))
这段代码输出如下:
base_data = [[ -9.63895991 6.9292461 -2.35654712 -48.45969283 13.56031937] [-39.75875796 -43.21031705 -49.27708561 6.80357128 33.71975059] [ 36.32228175 30.92546582 -41.63728955 28.68799187 6.44818484] [ 7.71568596 43.24884701 -14.90716555 -9.24092252 3.69738718] [-31.90994273 34.06067289 18.47830413 -16.02495202 -44.84625246]] np.amin(base_data) = -49.277085606595726 np.amax(base_data) = 43.24884701268845 np.average(base_data) = -3.22680706079886 np.sum(base_data) = -80.6701765199715 np.sin(base_data) = [[ 0.21254814 0.60204578 -0.70685739 0.9725159 0.8381861 ] [-0.88287359 0.69755541 0.83514527 0.49721505 0.74315189] [-0.98124746 -0.47103234 0.7149727 -0.40196147 0.16425187] [ 0.99045239 -0.66943662 -0.71791164 -0.18282139 -0.5276184 ] [-0.4741657 0.47665553 -0.36278223 0.31170676 -0.76041722]]
矩阵
接下来我们看一下以矩阵的方式使用NumPy。
首先,我们创建一个5X5的随机数整数矩阵。有两种方式可以获得矩阵的转置:通过.T或者transpose函数。另外, 通过dot函数可以进行矩阵的乘法,示例代码如下:
# matrix.py import numpy as np base_data = np.floor((np.random.random((5, 5)) - 0.5) * 100) print("base_data = \n{}\n".format(base_data)) print("base_data.T = \n{}\n".format(base_data.T)) print("base_data.transpose() = \n{}\n".format(base_data.transpose())) matrix_one = np.ones((5, 5)) print("matrix_one = \n{}\n".format(matrix_one)) minus_one = np.dot(matrix_one, -1) print("minus_one = \n{}\n".format(minus_one)) print("np.dot(base_data, minus_one) = \n{}\n".format( np.dot(base_data, minus_one))) 这段代码输出如下: base_data = [[-49. -5. 11. -13. -41.] [ -6. -33. -33. -47. -4.] [-38. 26. 28. -18. 18.] [ -3. -19. -15. -39. 45.] [-43. 6. 18. -15. -21.]] base_data.T = [[-49. -6. -38. -3. -43.] [ -5. -33. 26. -19. 6.] [ 11. -33. 28. -15. 18.] [-13. -47. -18. -39. -15.] [-41. -4. 18. 45. -21.]] base_data.transpose() = [[-49. -6. -38. -3. -43.] [ -5. -33. 26. -19. 6.] [ 11. -33. 28. -15. 18.] [-13. -47. -18. -39. -15.] [-41. -4. 18. 45. -21.]] matrix_one = [[ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.]] minus_one = [[-1. -1. -1. -1. -1.] [-1. -1. -1. -1. -1.] [-1. -1. -1. -1. -1.] [-1. -1. -1. -1. -1.] [-1. -1. -1. -1. -1.]] np.dot(base_data, minus_one) = [[ 97. 97. 97. 97. 97.] [ 123. 123. 123. 123. 123.] [ -16. -16. -16. -16. -16.] [ 31. 31. 31. 31. 31.] [ 55. 55. 55. 55. 55.]]
随机数
本文的最后,我们来看一下随机数的使用。
随机数是我们在编程过程中非常频繁用到的一个功能。例如:生成演示数据,或者将已有的数据顺序随机打乱以便分割出建模数据和验证数据。
numpy.random 包中包含了很多中随机数的算法。下面我们列举四种最常见的用法:
# rand.py import numpy as np print("random: {}\n".format(np.random.random(20))); print("rand: {}\n".format(np.random.rand(3, 4))); print("randint: {}\n".format(np.random.randint(0, 100, 20))); print("permutation: {}\n".format(np.random.permutation(np.arange(20))));
在四种用法分别是:
生成20个随机数,它们每一个都是[0.0, 1.0)之间
根据指定的shape生成随机数
生成指定范围内([0, 100))的指定数量(20)的随机整数
对已有的数据([0, 1, 2, ..., 19])的顺序随机打乱顺序
这段代码的输出如下所示:
random: [0.62956026 0.56816277 0.30903156 0.50427765 0.92117724 0.43044905 0.54591323 0.47286235 0.93241333 0.32636472 0.14692983 0.02163887 0.85014782 0.20164791 0.76556972 0.15137427 0.14626625 0.60972522 0.2995841 0.27569573] rand: [[0.38629927 0.43779617 0.96276889 0.80018417] [0.67656892 0.97189483 0.13323458 0.90663724] [0.99440473 0.85197677 0.9420241 0.79598706]] randint: [74 65 51 34 22 69 81 36 73 35 98 26 41 84 0 93 41 6 51 55] permutation: [15 3 8 18 14 19 16 1 0 4 10 17 5 2 6 12 9 11 13 7]
相关推荐:
以上是Python 機器學習庫 NumPy的詳細內容。更多資訊請關注PHP中文網其他相關文章!

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境