Python:一篇文章掌握Numpy的基本用法

2021-01-14 Python數據之道

前言

Numpy是一個開源的Python科學計算庫,它是python科學計算庫的基礎庫,許多其他著名的科學計算庫如Pandas,Scikit-learn等都要用到Numpy庫的一些功能。

本文主要內容如下:

Numpy數組對象

創建ndarray數組

Numpy的數值類型

ndarray數組的屬性

ndarray數組的切片和索引

處理數組形狀

數組的類型轉換

numpy常用統計函數

數組的廣播

1 Numpy數組對象

Numpy中的多維數組稱為ndarray,這是Numpy中最常見的數組對象。ndarray對象通常包含兩個部分:

Numpy數組的優勢

關於向量化和標量化運算,對比下面的參考例子就可以看出差異

def pySum():

   a = list(range(10000))

   b = list(range(10000))

   c = []

   for i in range(len(a)):

       c.append(a[i]**2 + b[i]**2)

   return c

%timeit pySum()

10 loops, best of 3: 49.4 ms per loop

import numpy as np

def npSum():

   a = np.arange(10000)

   b = np.arange(10000)

   c = a**2 + b**2

   return c

%timeit npSum()

The slowest run took 262.56 times longer than the fastest. This could mean that an intermediate result is being cached.

1000 loops, best of 3: 128 µs per loop

從上面的運行結果可以看出,numpy的向量化運算的效率要遠遠高於python的循環遍歷運算(效率相差好幾百倍)。 (1ms=1000µs)

2 創建ndarray數組

首先需要導入numpy庫,在導入numpy庫時通常使用「np」作為簡寫,這也是Numpy官方倡導的寫法。

當然,你也可以選擇其他簡寫的方式或者直接寫numpy,但還是建議用「np」,這樣你的程序能和大都數人的程序保持一致。

import numpy as np

創建ndarray數組的方式有很多種,這裡介紹我使用的較多的幾種:

Method 1: 基於list或tuple

# 一維數組

# 基於list

arr1 = np.array([1,2,3,4])

print(arr1)

# 基於tuple

arr_tuple = np.array((1,2,3,4))

print(arr_tuple)

# 二維數組 (2*3)

arr2 = np.array([[1,2,4], [3,4,5]])

arr2

[1 2 3 4]

[1 2 3 4]

array([[1, 2, 4],

      [3, 4, 5]])

請注意:

一維數組用print輸出的時候為 [1 2 3 4],跟python的列表是有些差異的,沒有「,

在創建二維數組時,在每個子list外面還有一個"[]",形式為「[[list1], [list2]]

Method 2: 基於np.arange

# 一維數組

arr1 = np.arange(5)

print(arr1)

# 二維數組

arr2 = np.array([np.arange(3), np.arange(3)])

arr2

[0 1 2 3 4]

array([[0, 1, 2],

      [0, 1, 2]])

Method 3: 基於arange以及reshape創建多維數組

# 創建三維數組

arr = np.arange(24).reshape(2,3,4)

arr

array([[[ 0,  1,  2,  3],

       [ 4,  5,  6,  7],

       [ 8,  9, 10, 11]],

      [[12, 13, 14, 15],

       [16, 17, 18, 19],

       [20, 21, 22, 23]]])

3 Numpy的數值類型

Numpy的數值類型如下:

每一種數據類型都有相應的數據轉換函數,參考示例如下:

np.int8(12.334)

12

np.float64(12)

12.0

np.float(True)

1.0

bool(1)

True

在創建ndarray數組時,可以指定數值類型:

a = np.arange(5, dtype=float)

a

array([ 0.,  1.,  2.,  3.,  4.])

# float(42 + 1j)

4 ndarray數組的屬性

np.arange(4, dtype=float)

array([ 0.,  1.,  2.,  3.])

# 'D'表示複數類型

np.arange(4, dtype='D')

array([ 0.+0.j,  1.+0.j,  2.+0.j,  3.+0.j])

np.array([1.22,3.45,6.779], dtype='int8')

array([1, 3, 6], dtype=int8)

a = np.array([[1,2,3], [7,8,9]])

a.ndim

2

a.shape

(2, 3)

a.size

6

a.itemsize

4

a.nbytes

24

a.size*a.itemsize

24

b = np.arange(24).reshape(4,6)

b

array([[ 0,  1,  2,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11],

      [12, 13, 14, 15, 16, 17],

      [18, 19, 20, 21, 22, 23]])

b.T

array([[ 0,  6, 12, 18],

      [ 1,  7, 13, 19],

      [ 2,  8, 14, 20],

      [ 3,  9, 15, 21],

      [ 4, 10, 16, 22],

      [ 5, 11, 17, 23]])

d = np.array([1.2+2j, 2+3j])

d

array([ 1.2+2.j,  2.0+3.j])

real屬性返回數組的實部

d.real

array([ 1.2,  2. ])

imag屬性返回數組的虛部

d.imag

array([ 2.,  3.])

e = np.arange(6).reshape(2,3)

e

array([[0, 1, 2],

      [3, 4, 5]])

f = e.flat

f

<numpy.flatiter at 0x65eaca0>

for item in f:

   print(item)

0

1

2

3

4

5

可通過位置進行索引,如下:

f[2]

2

f[[1,4]]

array([1, 4])

也可以進行賦值

e.flat=7

e

array([[7, 7, 7],

      [7, 7, 7]])

e.flat[[1,4]]=1

e

array([[7, 1, 7],

      [7, 1, 7]])

下圖是對ndarray各種屬性的一個小結


5 ndarray數組的切片和索引

一維數組的切片和索引與python的list索引類似。

a =  np.arange(7)

a

array([0, 1, 2, 3, 4, 5, 6])

a[1:4]

array([1, 2, 3])

# 每間隔2個取一個數

a[ : 6: 2]

array([0, 2, 4])


插播一條硬廣:技術文章轉發太多。本文涉及的代碼量比較多,如需要查看原始碼,請在微信公眾號「Python數據之道」(ID:PyDataRoad)後臺回復關鍵字「2017026」。

6 處理數組形狀6.1 形狀轉換

b.reshape(4,3)

array([[ 0,  1,  2],

      [ 3,  4,  5],

      [ 6,  7,  8],

      [ 9, 10, 11]])

b

array([[ 0,  1,  2,  3],

      [ 4,  5,  6,  7],

      [ 8,  9, 10, 11]])

b.resize(4,3)

b

array([[ 0,  1,  2],

      [ 3,  4,  5],

      [ 6,  7,  8],

      [ 9, 10, 11]])

函數resize()的作用跟reshape()類似,但是會改變所作用的數組,相當於有inplace=True的效果

b.ravel()

array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

b.flatten()

array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

b

array([[ 0,  1,  2],

      [ 3,  4,  5],

      [ 6,  7,  8],

      [ 9, 10, 11]])

兩者的區別在於返回拷貝(copy)還是返回視圖(view),flatten()返回一份拷貝,需要分配新的內存空間,對拷貝所做的修改不會影響原始矩陣,而ravel()返回的是視圖(view),會影響原始矩陣。

參考如下代碼:


b.shape=(2,6)

b

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11]])

前面描述了數組轉置的屬性(T),也可以通過transpose()函數來實現

b.transpose()

array([[ 0,  6],

      [ 1,  7],

      [20,  8],

      [ 3,  9],

      [ 4, 10],

      [ 5, 11]])

6.2 堆疊數組

b

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11]])

c = b*2

c

array([[ 0,  2, 40,  6,  8, 10],

      [12, 14, 16, 18, 20, 22]])

hstack()

np.hstack((b,c))

array([[ 0,  1, 20,  3,  4,  5,  0,  2, 40,  6,  8, 10],

      [ 6,  7,  8,  9, 10, 11, 12, 14, 16, 18, 20, 22]])

column_stack()函數以列方式對數組進行疊加,功能類似hstack()

np.column_stack((b,c))

array([[ 0,  1, 20,  3,  4,  5,  0,  2, 40,  6,  8, 10],

      [ 6,  7,  8,  9, 10, 11, 12, 14, 16, 18, 20, 22]])

vstack()

np.vstack((b,c))

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11],

      [ 0,  2, 40,  6,  8, 10],

      [12, 14, 16, 18, 20, 22]])

row_stack()函數以行方式對數組進行疊加,功能類似vstack()

np.row_stack((b,c))

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11],

      [ 0,  2, 40,  6,  8, 10],

      [12, 14, 16, 18, 20, 22]])

axis=1時,沿水平方向疊加

axis=0時,沿垂直方向疊加

np.concatenate((b,c),axis=1)

array([[ 0,  1, 20,  3,  4,  5,  0,  2, 40,  6,  8, 10],

      [ 6,  7,  8,  9, 10, 11, 12, 14, 16, 18, 20, 22]])

np.concatenate((b,c),axis=0)

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11],

      [ 0,  2, 40,  6,  8, 10],

      [12, 14, 16, 18, 20, 22]])

由於針對數組的軸為0或1的方向經常會混淆,通過示意圖,或許可以更好的理解。

關於數組的軸方向示意圖,以及疊加的示意圖,如下:

這個有點燒腦,舉個例子如下,自己可以體會下:

arr_dstack = np.dstack((b,c))

print(arr_dstack.shape)

arr_dstack

(2, 6, 2)

array([[[ 0,  0],

       [ 1,  2],

       [20, 40],

       [ 3,  6],

       [ 4,  8],

       [ 5, 10]],

      [[ 6, 12],

       [ 7, 14],

       [ 8, 16],

       [ 9, 18],

       [10, 20],

       [11, 22]]])

疊加前,b和c均是shape為(2,6)的二維數組,疊加後,arr_dstack是shape為(2,6,2)的三維數組。

深度疊加的示意圖如下:

6.3 數組的拆分

跟數組的疊加類似,數組的拆分可以分為橫向拆分、縱向拆分以及深度拆分。

涉及的函數為 hsplit()、vsplit()、dsplit() 以及split()

b

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11]])

np.hsplit(b, 2)

[array([[ 0,  1, 20],

       [ 6,  7,  8]]), array([[ 3,  4,  5],

       [ 9, 10, 11]])]

np.split(b,2, axis=1)

[array([[ 0,  1, 20],

       [ 6,  7,  8]]), array([[ 3,  4,  5],

       [ 9, 10, 11]])]

np.vsplit(b, 2)

[array([[ 0,  1, 20,  3,  4,  5]]), array([[ 6,  7,  8,  9, 10, 11]])]

np.split(b,2,axis=0)

[array([[ 0,  1, 20,  3,  4,  5]]), array([[ 6,  7,  8,  9, 10, 11]])]

arr_dstack

array([[[ 0,  0],

       [ 1,  2],

       [20, 40],

       [ 3,  6],

       [ 4,  8],

       [ 5, 10]],

      [[ 6, 12],

       [ 7, 14],

       [ 8, 16],

       [ 9, 18],

       [10, 20],

       [11, 22]]])

np.dsplit(arr_dstack,2)

[array([[[ 0],

        [ 1],

        [20],

        [ 3],

        [ 4],

        [ 5]],

       [[ 6],

        [ 7],

        [ 8],

        [ 9],

        [10],

        [11]]]), array([[[ 0],

        [ 2],

        [40],

        [ 6],

        [ 8],

        [10]],

       [[12],

        [14],

        [16],

        [18],

        [20],

        [22]]])]

拆分的結果是原來的三維數組拆分成為兩個二維數組。

這個燒腦的拆分過程可以自行分析下~~

7 數組的類型轉換

b

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11]])

b.tolist()

[[0, 1, 20, 3, 4, 5], [6, 7, 8, 9, 10, 11]]

b.astype(float)

array([[  0.,   1.,  20.,   3.,   4.,   5.],

      [  6.,   7.,   8.,   9.,  10.,  11.]])

8 numpy常用統計函數

常用的函數如下:

請注意函數在使用時需要指定axis軸的方向,若不指定,默認統計整個數組。

b

array([[ 0,  1, 20,  3,  4,  5],

      [ 6,  7,  8,  9, 10, 11]])

np.max(b)

20

# 沿axis=1軸方向統計

np.max(b,axis=1)

array([20, 11])

# 沿axis=0軸方向統計

np.max(b,axis=0)

array([ 6,  7, 20,  9, 10, 11])

np.min(b)

0

np.ptp(b)

20

# 沿axis=0軸方向

np.ptp(b, axis=0)

array([ 6,  6, 12,  6,  6,  6])

# 沿axis=1軸方向

np.ptp(b, axis=1)

array([20,  5])

b.resize(4,3)

b

array([[ 0,  1, 20],

      [ 3,  4,  5],

      [ 6,  7,  8],

      [ 9, 10, 11]])

np.cumsum(b, axis=1)

array([[ 0,  1, 21],

      [ 3,  7, 12],

      [ 6, 13, 21],

      [ 9, 19, 30]], dtype=int32)

np.cumsum(b, axis=0)

array([[ 0,  1, 20],

      [ 3,  5, 25],

      [ 9, 12, 33],

      [18, 22, 44]], dtype=int32)

np.cumprod(b,axis=1)

array([[  0,   0,   0],

      [  3,  12,  60],

      [  6,  42, 336],

      [  9,  90, 990]], dtype=int32)

np.cumprod(b,axis=0)

array([[   0,    1,   20],

      [   0,    4,  100],

      [   0,   28,  800],

      [   0,  280, 8800]], dtype=int32)

9 數組的廣播

當數組跟一個標量進行數學運算時,標量需要根據數組的形狀進行擴展,然後執行運算。

這個擴展的過程稱為「廣播(broadcasting)」

b

array([[ 0,  1, 20],

      [ 3,  4,  5],

      [ 6,  7,  8],

      [ 9, 10, 11]])

d = b + 2

d

array([[ 2,  3, 22],

      [ 5,  6,  7],

      [ 8,  9, 10],

      [11, 12, 13]])

寫在最後

numpy涵蓋的內容其實是非常豐富的,本文僅僅介紹了numpy一些常用的基本功能,算是對numpy的一個入門級的簡單的較為全面的描述。

numpy官方的《Numpy Reference》文檔,光頁面數量就有1500+頁,如想要系統的學習numpy,建議仔細閱讀官方的參考文檔,可在其官方網站進行查閱。當然,資料都是英文版的,可能看起來難度稍微大點,看習慣了就好。

本文涉及的代碼量比較多,如需要查看原始碼,請在微信公眾號「Python數據之道」(ID:PyDataRoad)後臺回復關鍵字「2017026」。


更多精彩文章

請點擊微信公眾號底部菜單欄。

相關閱讀:

為什麼你用不好Numpy的random函數?

Pandas日期數據處理:如何按日期篩選、顯示及統計數據

用Pandas獲取商品期貨價格並可視化



相關焦點

  • Python的武器庫05:numpy模塊(下)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以有這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。
  • 資源|用Python和NumPy學習《深度學習》中的線性代數基礎
    本文系巴黎高等師範學院在讀博士 Hadrien Jean 的一篇基礎學習博客,其目的是幫助初學者/高級初學者基於深度學習和機器學習來掌握線性代數的概念。掌握這些技能可以提高你理解和應用各種數據科學算法的能力。
  • Python模塊NumPy,Pandas,matplotlib的中文文檔
    今天比較忙所以不能寫長文了作為一名數據工程師需要熟練掌握python中的這些numpy,matplotlib,pandas,sklearn,seaborn,statsmodel.模塊但是由於這些模塊的文檔都是英文的可能一些英文不好的同學學起來會比較的困難,所以我從網上給大家找到一些中文的文檔
  • 如果不懂Numpy,請別說自己是Python程式設計師
    幸運的是,後來我遇到了 numpy 這個神器。numpy 是 python 科學計算的基礎軟體包,提供多了維數組對象,多種派生對象(掩碼數組、矩陣等)以及用於快速操作數組的函數及 API,它包括數學、邏輯、數組形狀變換、排序、選擇、I/O 、離散傅立葉變換、基本線性代數、基本統計運算、隨機模擬等等。
  • 不懂NumPy 算什麼 Python 程式設計師?|CSDN 博文精選
    NumPy 是 Python 科學計算的基礎軟體包,提供多維數組對象,多種派生對象(掩碼數組、矩陣等)以及用於快速操作數組的函數及 API,它包括數學、邏輯、數組形狀變換、排序、選擇、I/O 、離散傅立葉變換、基本線性代數、基本統計運算、隨機模擬等等。
  • 好程式設計師Python培訓分享numpy簡介
    二、numpy安裝 numpy要求python版本在3.5以上 1.windows下的安裝 · pip安裝 python -m pip install
  • python數據科學系列:numpy入門詳細教程
    numerical python縮寫,提供了底層基於C語言實現的數值計算庫,與python內置的list和array數據結構相比,其支持更加規範的數據類型和極其豐富的操作接口,速度也更快numpy的兩個重要對象是ndarray和ufunc,其中前者是數據結構的基礎,後者是接口方法的基礎ufunc,通函數,其意義是可以像執行標量運算一樣執行數組運算,本質即是通過隱式的循環對各個位置依次進行標量運算
  • Python的武器庫04:numpy模塊(上)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以又這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。Python正式由於這些模塊的出現,只要引入這個模塊,調用這個模塊的集成函數,問題迎刃而解;不需要從頭開始,節省了大量的時間。
  • Python學習第114課——numpy中ndarray的四則運算
    【每天幾分鐘,從零入門python編程的世界!】我們為什麼要學習numpy?numpy其實就是number+Python的簡寫,意思就是通過Python對數據進行處理。要對數據進行處理,就少不了最基本的加減乘除等操作。
  • Python NumPy用法介紹
    使用下面格式約定,引入NumPy包:import numpy as npNumPy的ndarray:N維數組對象NumPy最重要的是其N維數組對象(即ndarray),其中的所有元素必須是相同類型的。但修改原數組(維度變換).swapaxes(ax1,ax2) 將數組n個維度中兩個維度進行調換(維度變換).flatten():對數組進行降維,返回摺疊後的一維數組,原數組不變(維度變換).tolist():將N維數組轉換成列表(維度變換)ndarray數組的索引和切片具體使用參考https://seancheney.gitbook.io/python-for-data-analysis
  • Python學習第116課——numpy.dot和矩陣相乘的數學運算
    【每天幾分鐘,從零入門python編程的世界!】關於numpy中數組的相乘,我們學習了對位相乘(用numpy.multiply、或*直接相乘,比如數組a和b的對位相乘就是numpy.multiply(a,b)或a*b)和一維數組的點乘(dot product,也有人叫inner product,比如一維數組a和b的點乘就是a.b)。
  • python數據分析基礎之numpy
    支持高級大量的維度數組與矩陣運算,是學習數據挖掘的基礎,今天我們就來總結下numpy的一些基礎用法。首先,在講numpy之前,我先帶領大家預習下大學學習過的矩陣的基礎知識。1、矩陣的基本概念矩陣:由m×n個數排列成 的m行n列的數表,稱為m行n列矩陣。實矩陣:元素是實數的矩陣。復矩陣:元素是負數的矩陣。
  • Numpy應用整理
    numpy簡介numpy是python最為常用的庫,沒有之一,它表示Numeric Python,從名字也可以看出來,它被用來做數值計算,常與scipy配合使用。python運行慢還有一個重要原因就是python存放數據時往往不是在連續區域,這樣就導致數據的索引效率不高。而numpy則採用了C的邏輯,將np.array數據放在連續區域,提高批量數據的讀寫速度。
  • 一文包會,教你如何熟練運用Python數值計算Numpy包
    好啦,下面就說一下numpy包常用到的一些基本方法吧!numpy包中arange()函數的用法首先看一下arange()函數的語法格式吧:numpy.arange(start, stop, step)看到了嗎,arange()函數有三個參數哦,
  • Python學習第119課——numpy中的broadcasting
    【每天幾分鐘,從零入門python編程的世界!】這節課我們學習numpy中的數據的一個多變的特性--broadcasting,broadcasting的官方的說明比較麻煩,我們這裡把它簡化一下,就把它當做「腦補」的意思。我們舉例來說明。
  • Numpy入門詳細教程
    >numpy入門詳細教程python數據科學基礎庫主要是三劍客:numpy,pandas以及matplotlib,每個庫都集成了大量的方法接口,配合使用功能強大。numpy:numerical python縮寫,提供了底層基於C語言實現的數值計算庫,與python內置的list和array數據結構相比,其支持更加規範的數據類型和極其豐富的操作接口,速度也更快n
  • 基本初等函數 指數函數 代碼篇
    由於機器學習和數學密切相關,尤其是數學中的函數,因此我們非常有必要複習和了解基本的函數知識。上一篇文章中,我們為大家介紹了基本初等函數中的指數函數 基本初等函數 指數函數,本文將為大家介紹如何利用python語言完成函數的繪製。
  • 打工人打工魂,打工的必會java調用python的幾種用法
    本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】,經微信公眾號授權轉載,如需轉載與原文作者聯繫圖丨pexelsjava調用python的幾種用法(看這篇就夠了)在java類中直接執行python語句準備工作:創建maven工程,結構如下:到官網https://www.jython.org
  • Python學習第117課——numpy中dot的運用舉例
    【每天幾分鐘,從零入門python編程的世界!】上節我們學習了最基礎的matrix的運算,可能有小夥伴覺得這都要涉及高等數學知識了,確實如果你想做數據科學、做人工智慧,統計學、概率論等數學知識,尤其是算法是繞不過去的坎,但是不要怕!!!
  • Python使用ctypes模塊調用DLL函數之C語言數組與numpy數組傳遞
    詳細細節請參考:python使用ctypes模塊調用DLL函數之傳遞數值、指針與字符串參數、Python使用ctypes模塊調用DLL函數之傳遞結構體參數這次講一下在Python中使用ctypes模塊調用DLL中的庫函數傳遞數組參數的情況。