數據分析與數據挖掘 - 04科學計算

一 認識科學計算

在人工智能的研發中,其本質就是把一切問題轉化爲數學問題,因此數學運算很是重要。不少數學運算採用的都是numpy這個庫,由於它提供了很是多的科學計算的方法,能讓咱們的工做變得很是便利,這一章我將從numpy的基本使用開始,逐漸解決掉那些數學問題,讓Python與數學可以更緊密的結合在一塊兒。python

二 認識numpy

numpy的本質其實仍是一個多維數組,雖然咱們以前學習過數組對象(Python中的list或者tuple)和numpy的數據看似同樣,可是數組是沒法直接參與數值運算的,而numpy對象卻能夠。算法

三 數組建立

import numpy as np

arr1 = np.array([1, 2, 3, 4, 5, 6])
arr2 = np.array([[1, 2, 3, 4, ], [5, 6, 7, 8, ]])
print(arr1, arr1.shape, arr1.dtype)
print(arr2, arr2.shape, arr1.dtype)  # shape獲取數組形狀2行4列,dtype獲取數組中元素類型

若是咱們建立數組時,元素類型不同,numpy會給咱們自動處理成同樣的。數組

arr3 = np.array([1, 2.5, 3])  # 只要數組元素中出現float類型,就會所有處理成float
print(arr3, arr3.dtype)
arr4 = np.array(['4', 5, 5.6])  # 只要數組元素中出現str,就會所有處理成str
print(arr4, arr4.dtype)

四 數組訪問

numpy的訪問與Python中list或者tuple訪問原理同樣,方法也很是相似,只不過是加了一個緯度的概念。less

# 首先咱們定義了一個二維數組
arr5 = np.array([[1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9],
                 [10, 11, 12]])

print(arr5[1])  # 第一行 [4 5 6]
print(arr5[1][0])  # 第一行第0個 4
print(arr5[:, 2])  # 全部行第2個 [ 3  6  9 12]
print(arr5[:2])  # 前2行 [[1 2 3] [4 5 6]]
print(arr5[1, :])  # 第1行全部列 [4 5 6]
print(arr5[:, 1:2])  # 全部行第2到第3列 [[ 2] [ 5] [ 8] [11]]

對於二維來講,若是有逗號,逗號前是行篩選,逗號後是列篩選。對於n維來講,第一個逗號前是第一維,後面依次是二維三維等。ide

五 形狀處理

1 預覽修改與真正修改

numpy對象有一個shape屬性,在Python基礎中,對於形狀並不敏感,而在科學計算中,形狀卻很重要,在後面的算法模型計算中,咱們會使用地很頻繁。函數

# 定義一個6行3列的numpy數組對象
arr6 = np.array([[1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9],
                 [10, 11, 12],
                 [13, 14, 15],
                 [16, 17, 18]])

print(arr6.shape)  # 注意看每次打印的結果
print(arr6.reshape(2, 9))  # 獲得一個新的形狀,原來的對象不變
print(arr6.shape, arr6)
print(arr6.resize(2, 9))  # 無返回值,真正修改
print(arr6.shape, arr6)

咱們在這段代碼中,分別使用了reshape和resize兩種方法來對數組進行形狀上的改變。其中reshape只是返回改變形狀後的預覽狀態,或者說若是咱們要使用這個結果只能把結果賦值給一個單獨的變量,而後再進行使用。resize方法的返回結果爲空,可是它卻真正的改變了組數的形狀,仔細看打印結果你就可以發現這兩種形狀操做方法的區別了。學習

2 降維操做

降維是人工智能算法中很是經常使用且重要的一個操做,緣由是有時咱們去描述一個事物的特徵時,會有很是多的維度,但過多的維度會給咱們的計算帶來麻煩,這個時候咱們就須要去下降它的維度,而後再進行計算。人工智能

arr7 = np.array([[1, 10, 100], [2, 20, 200], [3, 30, 300]])

# 按照數組的行順序降至一維
print(arr7)
print(arr7.ravel())
print(arr7.reshape(-1))
print(arr7.flatten())

# 按照大小順序降至一維
print(arr7.ravel(order="F"))
print(arr7.reshape(-1, order="F"))
print(arr7.flatten(order="F"))

降維後再進行修改code

print('ravel:{}'.format(arr7.ravel()))
arr7.ravel()[1] = 1000
print(arr7)

print('reshape: {}'.format(arr7.reshape(-1)))
arr7.reshape(-1)[2] = 3000
print(arr7)

print('flatten: {}'.format(arr7.flatten()))
arr7.flatten()[0] = 2000
print(arr7)

從結果中,咱們看到經過flatten方法實現的降維返回的是複製的操做,若是要用,那麼只能把結果賦值給另外的變量了。它並無影響原來數組的結果。經過ravel和reshape兩個方法,返回的則是視圖,也就是經過對視圖的修改,是會直接影響到原數組中的值的。orm

3 數組堆疊

arr8 = np.array([[1, 10, 100], [2, 20, 200], [3, 30, 300]])
arr9 = np.array([1, 2, 3])
arr10 = np.array([[5], [6], [7]])

# 縱向堆疊
print(np.vstack([arr8, arr9]))
print(np.row_stack([arr8, arr9]))

# 橫向合併
print(np.hstack([arr8, arr10]))
print(np.column_stack([arr8, arr10]))

須要注意的是:多個數組橫向堆疊時,要保證行數相同,縱向合併,則要保證列數相同。

六 基本運算

1 四則運算

在之前,咱們若是要對兩個同形狀的數組進行對應位置的四則運算時,咱們必需要對兩個數組進行循環處理,代碼量上來講並很多,而且容易出錯。有了NumPy以後,這些運算將會變的很是的簡單。

import numpy as np

arr1 = np.array([11, 12, 13])
arr2 = np.array([21, 22, 23])
arr3 = np.array([31, 32, 33])

print(arr1 + arr2)
print(arr1 + arr2 + arr3)
print(arr1 - arr2)
print(arr1 - arr2 - arr3)
print(arr1 * arr2)
print(arr1 * arr2 * arr3)
print(arr1 / arr2)
print(arr1 / arr2 / arr3)
print(arr1 // arr2)
print(arr1 % arr2)
print(arr1 ** arr2)

print(np.add(arr1, arr2))
print(np.add(np.add(arr1, arr2), arr3))
print(np.subtract(arr1, arr2))
print(np.multiply(arr1, arr2))
print(np.divide(arr1, arr2))

從代碼的運行結果中咱們能夠看到,當咱們使用符號進行四則運算的時候,是能夠連續進行操做的。當咱們使用對象的方法進行四則運算的時候,不能夠連續進行操做,由於這個方法只接收兩個參數。若是咱們想要對多個數組對象進行操做的時候,咱們必須使用方法嵌套的方式來進行操做。除了四則運算,在學習Python基礎時,所學習的取餘數、整除、冪運算等都是支持的。

2 比較運算

print(arr1 <= arr2)
print(arr1 == arr2)
print(arr1 != arr2)

print(np.greater(arr1, arr2))
print(np.greater_equal(arr1, arr2))
print(np.less(arr1, arr2))
print(np.less_equal(arr1, arr2))
print(np.equal(arr1, arr2))
print(np.not_equal(arr1, arr2))

從結果上看,運用比較運算符能夠返回布爾類型的值,也就是True和False。那咱們何時會用到這樣的運算呢?第一種狀況是從數組中查詢知足條件的元素,第二種狀況是根據判斷的結果執行不一樣的操做,示例代碼以下:

arr3 = np.array([23, 12, 25])
arr4 = np.array([21, 15, 23])

print(arr3[arr3 > arr4])  # 取出arr3中元素大於arr4的
print(arr3[arr3 > 24])  # 取出arr3中元素大於24的
print(np.where(arr3 > 24, 0, arr3))  # 相似三元表達式,把大於24的修改爲0,其餘不變
print(list(0 if x > 24 else x for x in arr3))
print(np.where(arr4 > 16, 0, arr4))

3 廣播運算

上面咱們全部的運算都是基於相同形狀的數組,那麼當數組形狀不一樣時,可以讓它們之間進行運算嗎?答案是確定的,可是有相應的規則,不能隨意計算,這種計算就叫作廣播運算。

# 1 廣播運算,末尾的緯度值加上去
arr3 = np.arange(60).reshape(5, 4, 3)
arr4 = np.arange(12).reshape(4, 3)
print(arr3)
print(arr4)
print(arr3 + arr4)

# 2 緯度值有一個爲1
arr5 = np.arange(60).reshape(5, 4, 3)
arr6 = np.arange(4).reshape(4, 1)
print(arr5)
print(arr6)
print(arr5 + arr6)

# 3 arr7會自動補齊,相似上面緯度值有一個爲1
arr7 = np.arange(12).reshape(4, 3)
arr8 = np.array([1, 2, 3])
print(arr7)
print(arr8)
print(arr7 + arr8)

arr9 = np.arange(60).reshape(5, 4, 3)
arr10 = np.arange(8).reshape(4, 2)
print(arr9)
print(arr10)
# print(arr9 + arr10)  # 不在上述三種討論範圍內,沒法運算

其實,廣播運算中的廣播就是一對多,它的規律就是二者有類似的地方能夠對應的上就能運算,缺乏的部分,會自動用相同的部分補齊。

七 數學函數

numpy提供給咱們一些常見的函數,除了np.pi或者np.e這樣的常量函數,numpy也提供給咱們不少數學函數供咱們直接調用。

import numpy as np

arr1 = np.array([1.3, 1.5, -1.8, 2.4, 3.2])
arr2 = np.array([1, 2, 3, 4, 5])

print(np.fabs(arr1))  # 絕對值
print(np.ceil(arr1))  # 向上取整
print(np.floor(arr1))  # 向下取整
print(np.round(arr1))  # 四捨五入
print(np.fmod(arr2, arr1))  # 餘數
print(np.modf(arr1))  # 取小數部分和整數部分
print(np.sqrt(arr2))  # 算法平方根
print(np.square(arr2))  # 平方
print(np.exp(arr2))  # 以e爲底的指數
print(np.power(arr2, 3))  # 各元素的3次方
print(np.log2(arr2))  # 以2爲底的對數
print(np.log10(arr2))  # 以10爲底的對數
print(np.log(arr2))  # 以e爲底的對數

八 軸方向

數組對象有幾個維度就有幾個軸,對於咱們常見的二維數組來講,軸0是豎直方向,軸1是水平方向。

import numpy as np

arr1 = np.array([[3, 7, 25, 8, 15, 20],
                 [4, 5, 6, 9, 14, 21]])

print(arr1)
print(np.max(arr1))  # 全部數組元素最大值
print(np.max(arr1, axis=1))  # 軸1最大值
print(np.max(arr1, axis=0))  # 軸0最大值

numpy提供了不少能夠按照軸方向來計算的函數。

print(np.min(arr1, axis=0))  # 最小值
print(np.min(arr1, axis=1))
print(np.mean(arr1, axis=0))  # 平均值
print(np.median(arr1, axis=0))  # 中位數
print(np.sum(arr1, axis=1))  # 求和
相關文章
相關標籤/搜索