python_numPy學習

weixin_34107955發表於2018-04-14

原文連結

numPy


維基百科

特點

NumPy引用CPython(一個使用位元組碼的直譯器),而在這個Python實現直譯器上所寫的數學演算法程式碼通常遠比編譯過的相同程式碼要來得慢。為了解決這個難題,NumPy引入了多維陣列以及可以直接有效率地操作多維陣列的函式與運算子。因此在NumPy上只要能被表示為針對陣列或矩陣運算的演算法,其執行效率幾乎都可以與編譯過的等效C語言程式碼一樣快。[1]

NumPy提供了與MATLAB相似的功能與操作方式,因為兩者皆為解釋型語言,並且都可以讓使用者在針對陣列或矩陣運算時提供較標量運算更快的效能。兩者相較之下,MATLAB提供了大量的擴充工具箱(例如Simulink);而NumPy則是根基於Python這個更現代、完整並且開放原始碼的程式語言之上。此外NumPy也可以結合其它的Python擴充庫。例如SciPy,這個庫提供了更多與MATLAB相似的功能;以及Matplotlib,這是一個與MATLAB內建繪圖功能類似的庫。而從本質上來說,NumPy與MATLAB同樣是利用BLAS與LAPACK來提供高效率的線性代數運算。

ndarray 資料結構

NumPy的核心功能是"ndarray"(即n-dimensional array,多維陣列)資料結構。這是一個表示多維度、同質並且固定大小的陣列物件。而由一個與此陣列相關係的資料型別物件來描述其陣列元素的資料格式(例如其字元組順序、在儲存器中佔用的字元組數量、整數或者浮點數等等)。

陣列建立


NumPy的基礎是一個同構的多維資料,陣列中的元素可以通過下標來索引。在NumPy中,維度稱之為axis(複數是axes),維度的數量稱之為rank。

首先獲取NumPy,具體方式請開啟連結

預設書寫方式

import numpy as np

建立data1、data2兩個普通陣列,data1的rank為1,axis的長度為6。data2的rank為2,axis的長度為4。

>>> data1 = [6,7.5,8,0,1]
>>> data2 = [[1,2,3,4],[5,6,7,8]]
>>> data1
[6, 7.5, 8, 0, 1]
>>> data2
[[1, 2, 3, 4], [5, 6, 7, 8]]

通過array函式來建立NumPy的陣列

>>> arr1 = np.array(data1)
>>> arr2 = np.array(data2)
>>> arr1
array([6. , 7.5, 8. , 0. , 1. ])
>>> arr2
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

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:儲存陣列元素的緩衝。通常我們只需要通過下標來訪問元素,而不需要訪問緩衝

ndarray屬性例項

>>> arr1.ndim
1
>>> arr2.ndim
2
>>> arr1.shape
(5,)
>>> arr2.shape
(2, 4)
>>> arr1.size
5
>>> arr2.size
8
>>> arr1.dtype
dtype('float64')
>>> arr2.dtype
dtype('int64')
>>> arr1.itemsize
8
>>> arr2.itemsize
8

建立指定的陣列


  • 指定rank為2:
>>> np.array([1, 2, 3], ndmin=2)
array([[1, 2, 3]])
  • 指定為complex型別的資料:
>>> np.array([1, 2, 3], dtype=complex)
array([1.+0.j, 2.+0.j, 3.+0.j])
  • 生成陣列並賦為特殊值:
    • ones:全1
    • zeros:全0
    • empty:隨機數,取決於記憶體情況
>>> np.zeros( (3,4) )
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> np.ones( (2,3,4), dtype=np.int16 )
array([[[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]],
       [[ 1, 1, 1, 1],
        [ 1, 1, 1, 1],
        [ 1, 1, 1, 1]]], dtype=int16)
>>> np.empty( (2,3) )
array([[  3.73603959e-262,   6.02658058e-154,   6.55490914e-260],
       [  5.30498948e-313,   3.14673309e-307,   1.00000000e+000]])
  • 生成均勻分佈的array:
    • arange(最小值,最大值,步長)(左閉右開)
    • linspace(最小值,最大值,元素數量)
>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])

>>> np.linspace( 0, 9, 10)
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
  • 生成隨機數random:
>>> np.random.random((2,3))
array([[0.41604856, 0.7216842 , 0.88832856],
       [0.42092882, 0.44241471, 0.07187805]])

Shape與操作

根據已有陣列進行相關的操作來產生一些新的資料結構

  • reshape:根據已有陣列和指定的shape,生成一個新的陣列
>>> b = np.array([1,2,3,4,5,6,7,8,9])
>>> b.reshape((3,3))
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

注意:形狀變化的原則是陣列元素不能發生改變,比如這樣寫就是錯誤的,因為陣列元素髮生了變化。

>>> b.reshape((4,3))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: cannot reshape array of size 10 into shape (4,3)
  • vstack:用來將多個陣列在垂直(v代表vertical)方向拼接(陣列的維度必須匹配)
>>> a1 = [1,2,3]
>>> a2 = [4,5,6]
>>> a3 = [7,8,9]
>>> np.vstack((a1,a2,a3))
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
  • hstack:用來將多個陣列在水平(h代表horizontal)方向拼接(陣列的維度必須匹配)
np.hstack((a1,a2,a3))
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
  • hsplit:用來將陣列在水平方向拆分
>>> b1 = np.vstack((a1,a2,a3))
>>> np.hsplit(b1,3)
[array([[1],
       [4],
       [7]]), array([[2],
       [5],
       [8]]), array([[3],
       [6],
       [9]])]
  • vsplit:用來將陣列在垂直方向拆分
>>> np.vsplit(b1,3)
[array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]

相關運算

  • 基本運算
>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> a > 35
array([False, False,  True,  True])
  • 陣列相乘,對應位置相乘
>>> ab1 = np.array([[1,2],[3,4]])
>>> ab2 = np.array([[5,6],[7,8]])
>>> ab1 * ab2
array([[ 5, 12],
       [21, 32]])
  • 矩陣乘法,使用dot
>>> ab1.dot(ab2)
array([[19, 22],
       [43, 50]])
  • 內建函式(min,max,sum),同時可以使用axis指定對哪一維進行操作
>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

書中案例


  • 1000個硬幣累計結果和


    5207977-1cc74304a56779c9.png
    1000個硬幣累計結果和

參考資料


1、SciPy.org
2、利用python進行資料分析 密碼: s8wx

相關文章