1. 程式人生 > >【資料分析】:Numpy基礎:陣列和向量運算

【資料分析】:Numpy基礎:陣列和向量運算

☆Numpy(Numerical Python)是高效能科學計算和資料分析的基礎包,它是幾乎所有資料分析高階工具的構建基礎。

  • ndarry ,一個具有向量算數運算和複雜廣播能力的快速且節省空間的多維陣列。
  • 用於對整組資料進行快速運算的標準數學函式(無需編寫迴圈)。
  • 用於讀寫磁碟資料的工具以及用於操作記憶體對映檔案的工具。
  • 線性代數、隨機數生成及傅立葉變換功能。
  • 用於整合由C,C++,Fortran等語言編寫的程式碼的工具CAPI,將資料傳遞給外部庫(生態系統角度)。
  • numpy本身並沒有提供多麼高階的資料分析功能,理解Numpy陣列以及面向陣列的計算將有助於你更加高效地使用pandas等工具。精通面向陣列的程式設計和思維方式是成為Python科學計算牛人的一大關鍵步驟。

☆對於大部分資料分析應用而言,最關注的功能主要集中於:

  • ①用於資料整理、自己構建、過濾、轉換等快速的向量化陣列運算。
  • ②常用的陣列演算法,如排序、唯一化、集合運算等。
  • ③高效的描述統計和資料聚合/摘要運算
  • ④用於異構資料集的合併/連線運算的資料對齊和關係型資料運算
  • ⑤將條件邏輯表述為陣列表示式(而不是帶有if-elif-else分支的迴圈)
  • ⑥資料的分組運算(聚合、轉換、函式應用等)。

Numpy的ndarry,一種多維陣列物件

  • Numpy最重要的一個特點就是其N維陣列物件:ndarry,該物件是一個快速而靈活的大資料集容器。可以利用這種陣列對整塊資料執行一些數學運算,其語法與標量元素之間的運算一樣。
  • ndarry是一個通用的同構資料多維容器,其中所有的元素必須是相同型別的。每個陣列都有一個shape(一個表示各維度大小的元組)和一個dtype(一個用於說明資料型別的物件)。
data.shape()     (2,3)
data.dtype()     ('float64')

①建立ndarry

  • 序列型的物件
data = [1,2,3,4]
arr = np.array(data)
  • 巢狀序列
    • 巢狀序列將會被轉換為一個多維陣列
  • np.array會嘗試為新建的陣列推斷出一個較為合適的資料型別,資料型別儲存在一個特殊的dtype物件中。
  • 其他的建立陣列的函式
np.zeros()   #指定長度或形狀的陣列全部為0
np.ones()    #指定長度或形狀的陣列全部為1
np.empty()   #空陣列
np.arange()  #python內建函式的陣列版

②ndarry的資料型別

  • dtype(資料型別)是一個特殊的物件,它含有ndarray將一塊記憶體解釋為特定資料型別所需的資訊:
arr = np.array([1,2,3],dtype = np.float64)
arr.dtype()
  • dtype是Numpy如此強大和靈活的原因之一。
  • Numpy的資料型別
    • int8/uint8——有符號和無符號
    • float64——浮點型
    • complex64——複數
    • bool——布林型
    • object——python物件型別
    • string_——字串型別
    • unicode——unicode型別
  • 可以通過ndarray的astype方法顯式地轉換其dtype
float_arr = arr.astype(np.float64)
  • 呼叫astype無論如何都會創建出一個新的陣列(原始資料的一份拷貝),即使新dtype跟以前的一樣

③陣列和標量之間的運算

  • 陣列很重要,因為它使你不用編寫迴圈即可對資料執行批量運算。這通常就叫做向量化。
  • 大小相等的任何算術運算都會將運算應用到元素級。
  • 陣列與標量的算術運算也會將那個標量值傳播到各個元素。
  • 不同大小的陣列之間的運算叫做廣播(廣播機制)

⑤基本的索引和切片

  • Numpy陣列的索引是一個內容豐富的主題,因為選取資料子集或單個元素的方式有很多。
  • 將一個標量值賦值給一個切片時,該值會自動廣播到整個選區。
  • 跟列表最重要的區別在於,陣列切片是原始陣列的檢視,這意味著資料不會被複制,檢視上的任何修改都會直接反映到源資料上。如果需要一份副本而非本檢視,則需要顯式複製操作:arr.copy()
  • numpy的設計目的是處理大資料。Numpy將資料來回複製的話將會產生很多效能和記憶體問題。
1)元素索引
  • 對於高維度陣列,能做的事情更多。在一個二維陣列中,各索引位置上的元素不再是標量,而是一維陣列。
  • 可以對高維陣列各個元素進行遞迴訪問,也可以傳入一個逗號隔開的索引列表來選取單個元素。
arr2d = np.array([1,2,3],[4,5,6],[7,8,9])
arr2d[0],[2] = arr2d[0,2] = 3
2)切片索引
  • nadrray的切片語法跟python列表這樣的一維物件差不多。
  • 高緯度物件的切片花樣比較多。可以在一個軸或者多個軸上進行切片,也可以跟整數索引混合使用。
arr2d[:2,1:]   #只能得到相同維數的陣列檢視
arr2d[1,:2]    #通過將整數索引和切片混合,可以得到低維度的切片
arr2d[:,:1]    #只有冒號表示選取整個軸
3)布林型索引
  • 判斷滿足條件
data[names = 'bob',2:]   #布林型陣列的長度必須跟被索引的軸長度一致,此外,還可以與切片、整數等混用
4)花式索引
  • 花式索引是一個Numpy術語,它指的是利用整數陣列進行索引
arr = np.empty((8,4))
arr[[4,3,0,6]]   #只需傳入一個用於指定順序的整數列表或ndarray即可
arr[[-3,-5,-7]]   #使用負數索引將會從末尾開始選取行
arr = np.arange(32).reshape((8,4))
arr[[1,5,7,2],[0,3,1,2]]   #一次傳入多個索引陣列會有些特別
5)陣列轉置和軸對換
  • 轉置(transpose)是重塑的一種特殊形式,它返回的是源資料的檢視(不會進行任何複製操作)
  • T屬性。進行矩陣計算時,經常需要用到該操作。

通用函式:快速的元素級陣列函式

  • 通用函式(ufunc)是一種對nadrray中的資料執行元素級運算的函式。可以將其看做簡單函式(接受一個或多個標量值,併產生一個 或多個標量值)的 向量化包裝器。
  • 許多ufunc都是簡單的元素級變體。如np.sqrt() /np.exp()
  • 一元ufunc(接受一個數組):
    • abs/fabs #絕對值 ,非負數的絕對值
    • sqrt #計算各元素平方根
    • square #計算各元素平方
    • exp #計算各元素指數
    • log/log10/log2/log1p #計算各元素的自然對數
    • sign #計算各元素的正負號
    • ceil #計算各元素的ceiling值,即大於等於該值的最小整數
    • floor #計算各元素的floor值,即小於等於該值的最大整數
    • rint #將各元素四捨五入到最接近的整數
    • modf #將陣列的小數和整數部分以兩個獨立陣列的形式返回
    • isnan #返回一個表示“哪些值是NaN”的布林型陣列
    • isfinite/isinf #返回表示無窮的布林型陣列
    • cos/cosh/sin/sinh/tan/tanh #三角函式
  • 二元ufunc(接受兩個陣列):
    • add #將陣列中對應的元素相加
    • subtract #從第一個陣列中減去第二個陣列中的元素
    • multiply #陣列元素相乘
    • divide/floor_divide #除法或向下圓整除法,丟棄餘數
    • power #計算第二個陣列元素b相對於第一個陣列中元素a的計算:a的b次方
    • maximum/fmax #元素級的最大值計算。忽略NaN
    • minimum/fmin #元素級的最小值計算。忽略NaN
    • copysign #將第二個陣列的值得符號複製給第一個陣列中對應的值
    • greater/greater_equal/less/less_equal/equal/not_equal #執行元素級的比較運算,最終產生布爾型陣列
    • logical_and/logical_or/logical_xor #執行元素級的真值邏輯運算 (與或非)

利用陣列進行資料處理

  • Numpy陣列可以將許多種資料處理任務表述為簡潔的陣列表示式(否則需要編寫迴圈)。
  • 用陣列表示式代替迴圈的做法,通常被稱作向量化。一般來說,向量化陣列運算比等價的純python方法快1~2個數量級(甚至更多)。