Python必備基礎:這些NumPy的神操作你都掌握了嗎?

2021-02-20 Python大本營

2019 Python開發者日」全日程揭曉,請掃碼諮詢 ↑↑↑

導讀:NumPy是Python的基礎,更是數據科學的通用語言。

本文簡單介紹NumPy模塊的兩個基本對象ndarray、ufunc,介紹ndarray對象的幾種生成方法及如何存取其元素、如何操作矩陣或多維數組、如何進行數據合併與展平等。最後說明通用函數及廣播機制。

作者:吳茂貴,王冬,李濤,楊本法

NumPy為何如此重要?實際上Python本身含有列表(list)和數組(array),但對於大數據來說,這些結構有很多不足。因列表的元素可以是任何對象,因此列表中所保存的是對象的指針。這樣為了保存一個簡單的[1,2,3],都需要有3個指針和3個整數對象。

對於數值運算來說,這種結構顯然比較浪費內存和CPU計算時間。至於array對象,它直接保存數值,和C語言的一維數組比較類似。但是由於它不支持多維,也沒有各種運算函數,因此也不適合做數值運算。

NumPy(Numerical Python 的簡稱)的誕生彌補了這些不足,它提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存儲單一數據類型的多維數組,而ufunc則是能夠對數組進行處理的函數。

NumPy的主要特點:

ndarray,快速,節省空間的多維數組,提供數組化的算術運算和高級的廣播功能。

使用標準數學函數對整個數組的數據進行快速運算,而不需要編寫循環。

讀取/寫入磁碟上的陣列數據和操作存儲器映像文件的工具。

線性代數,隨機數生成,以及傅立葉變換的能力。

集成C、C++、Fortran代碼的工具。

在使用 NumPy 之前,需要先導入該模塊:


01 生成ndarray的幾種方式

NumPy封裝了一個新的數據類型ndarray,一個多維數組對象,該對象封裝了許多常用的數學運算函數,方便我們進行數據處理以及數據分析,那麼如何生成ndarray呢?這裡我們介紹生成ndarray的幾種方式,如從已有數據中創建;利用random創建;創建特殊多維數組;使用arange函數等。

1. 從已有數據中創建

直接對python的基礎數據類型(如列表、元組等)進行轉換來生成ndarray。

(1)將列錶轉換成ndarray

import numpy as np
list1 = [3.14,2.17,0,1,2]
nd1 = np.array(list1)
print(nd1)
print(type(nd1))

列印結果:

[ 3.14  2.17  0.    1.    2.  ]
<class 'numpy.ndarray'>

(2)嵌套列表可以轉換成多維ndarray

import numpy as np
list2 = [[3.14,2.17,0,1,2],[1,2,3,4,5]]
nd2 = np.array(list2)
print(nd2)
print(type(nd2))

列印結果:

[[ 3.14  2.17  0.    1.    2.  ]
 [ 1.    2.    3.    4.    5.  ]]
<class 'numpy.ndarray'>

如果把(1)和(2)中的列表換成元組也同樣適合。

2. 利用random模塊生成ndarray

在深度學習中,我們經常需要對一些變量進行初始化,適當的初始化能提高模型的性能。通常我們用隨機數生成模塊random來生成,當然random模塊又分為多種函數:

random生成0到1之間的隨機數;

uniform生成均勻分布隨機數;

randn生成標準正態的隨機數;

normal生成正態分布;

shuffle隨機打亂順序;

seed設置隨機數種子等。

下面我們列舉幾個簡單示例。

import numpy as np

nd5 = np.random.random([3,3])
print(nd5)
print(type(nd5))

列印結果:

[[ 0.88900951  0.47818541  0.91813526]
 [ 0.48329167  0.63730656  0.14301479]
 [ 0.9843789   0.99257093  0.24003961]]
<class 'numpy.ndarray'>

生成一個隨機種子,對生成的隨機數打亂。

import numpy as np

np.random.seed(123)
nd5_1 = np.random.randn(2,3)
print(nd5_1)
np.random.shuffle(nd5_1)
print("隨機打亂後數據")
print(nd5_1)
print(type(nd5_1))

列印結果:

[[-1.0856306   0.99734545  0.2829785 ]
 [-1.50629471 -0.57860025  1.65143654]]

隨機打亂後數據為:

[[-1.50629471 -0.57860025  1.65143654]
 [-1.0856306   0.99734545  0.2829785 ]]
<class 'numpy.ndarray'>

3. 創建特定形狀的多維數組

數據初始化時,有時需要生成一些特殊矩陣,如0或1的數組或矩陣,這時我們可以利用np.zeros、np.ones、np.diag來實現,下面我們通過幾個示例來說明。

import numpy as np

#生成全是0的3x3矩陣
nd6 = np.zeros([3,3])
#生成全是1的3x3矩陣
nd7 = np.ones([3,3])
#生成3階的單位矩陣
nd8= np.eye(3)
#生成3階對角矩陣
print (np.diag([1, 2, 3]))

我們還可以把生成的數據保存到磁碟,然後從磁碟讀取。

import numpy as np
nd9 = np.random.random([5,5])
np.savetxt(X=nd9,fname='./test2.txt')
nd10 = np.loadtxt('./test2.txt')

4. 利用arange函數

arange是numpy模塊中的函數,其格式為:arange([start,] stop[, step,], dtype=None)。根據start與stop指定的範圍,以及step設定的步長,生成一個 ndarray,其中start默認為0,步長step可為小數。

import numpy as np

print(np.arange(10))
print(np.arange(0,10))
print(np.arange(1, 4,0.5))
print(np.arange(9, -1, -1))

02 存取元素

上節我們介紹了生成ndarray的幾種方法,數據生成後,如何讀取我們需要的數據?這節我們介紹幾種讀取數據的方法。

import numpy as np
np.random.seed(2018)
nd11 = np.random.random([10])
#獲取指定位置的數據,獲取第4個元素
nd11[3]
#截取一段數據
nd11[3:6]
#截取固定間隔數據
nd11[1:6:2]
#倒序取數
nd11[::-2]
#截取一個多維數組的一個區域內數據
nd12=np.arange(25).reshape([5,5])
nd12[1:3,1:3]
#截取一個多維數組中,數值在一個值域之內的數據
nd12[(nd12>3)&(nd12<10)]
#截取多維數組中,指定的行,如讀取第2,3行
nd12[[1,2]]  #或nd12[1:3,:]
##截取多維數組中,指定的列,如讀取第2,3列
nd12[:,1:3]

如果你對上面這些獲取方式還不是很清楚,沒關係,下面我們通過圖形的方式說明如何獲取多維數組中的元素,如圖1-1所示,左邊為表達式,右邊為對應獲取元素。

▲圖1-1 獲取多維數組中的元素

獲取數組中的部分元素除通過指定索引標籤外,還可以使用一些函數來實現,如通過random.choice函數從指定的樣本中進行隨機抽取數據。

import numpy as np
from numpy import random as nr

a=np.arange(1,25,dtype=float)
c1=nr.choice(a,size=(3,4))  #size指定輸出數組形狀
c2=nr.choice(a,size=(3,4),replace=False)  #replace預設為True,即可重複抽取
#下式中參數p指定每個元素對應的抽取概率,默認為每個元素被抽取的概率相同
c3=nr.choice(a,size=(3,4),p=a / np.sum(a))
 print("隨機可重複抽取")
print(c1)
print("隨機但不重複抽取")
print(c2)
print("隨機但按制度概率抽取")
print(c3)

列印結果:

隨機可重複抽取
[[  7.  22.  19.  21.]
 [  7.   5.   5.   5.]
 [  7.   9.  22.  12.]]
隨機但不重複抽取
[[ 21.   9.  15.   4.]
 [ 23.   2.   3.   7.]
 [ 13.   5.   6.   1.]]
隨機但按制度概率抽取
[[ 15.  19.  24.   8.]
 [  5.  22.   5.  14.]
 [  3.  22.  13.  17.]]

03 矩陣操作

深度學習中經常涉及多維數組或矩陣的運算,正好NumPy模塊提供了許多相關的計算方法,下面介紹一些常用的方法。

import numpy as np

nd14=np.arange(9).reshape([3,3])

#矩陣轉置
np.transpose(nd14)

#矩陣乘法運算
a=np.arange(12).reshape([3,4])
b=np.arange(8).reshape([4,2])
a.dot(b)

#求矩陣的跡
a.trace()
#計算矩陣行列式
np.linalg.det(nd14)

#計算逆矩陣
c=np.random.random([3,3])
np.linalg.solve(c,np.eye(3))

上面介紹的幾種方法是numpy.linalg模塊中的函數,numpy.linalg模塊中的函數是滿足行業標準級的Fortran庫。

numpy.linalg中常用函數:

04 數據合併與展平

在機器學習或深度學習中,會經常遇到需要把多個向量或矩陣按某軸方向進行合併的情況,也會遇到展平的情況,如在卷積或循環神經網絡中,在全連接層之前,需要把矩陣展平。這節介紹幾種數據合併和展平的方法。

1. 合併一維數組

import numpy as np
a=np.array([1,2,3])
b=np.array([4,5,6])
c=np.append(a,b)
print(c)
#或利用concatenate
d=np.concatenate([a,b])
print(d)

列印結果:

[1 2 3 4 5 6]
[1 2 3 4 5 6]

2. 多維數組的合併

import numpy as np
a=np.arange(4).reshape(2,2)
b=np.arange(4).reshape(2,2)
#按行合併
c=np.append(a,b,axis=0)
print(c)
print("合併後數據維度",c.shape)
#按列合併
d=np.append(a,b,axis=1)
print("按列合併結果:")
print(d)
print("合併後數據維度",d.shape)

列印結果:

[[0 1]
 [2 3]
 [0 1]
 [2 3]]
合併後數據維度 (4, 2)
按列合併結果:
[[0 1 0 1]
 [2 3 2 3]]
合併後數據維度 (2, 4) 

3. 矩陣展平

import numpy as np
nd15=np.arange(6).reshape(2,-1)
print(nd15)
#按照列優先,展平。
print("按列優先,展平")
print(nd15.ravel('F'))
#按照行優先,展平。
print("按行優先,展平")
print(nd15.ravel())

列印結果:

[[0 1 2]
 [3 4 5]]
按列優先,展平
[0 3 1 4 2 5]
按行優先,展平
[0 1 2 3 4 5]

05 通用函數

NumPy提供了兩種基本的對象,即ndarray和ufunc對象。前面我們對ndarray做了簡單介紹,本節將介紹它的另一個對象ufunc。

ufunc(通用函數)是universal function的縮寫,它是一種能對數組的每個元素進行操作的函數。許多ufunc函數都是在C語言級別實現的,因此它們的計算速度非常快。

此外,功能比math模塊中的函數更靈活。math模塊的輸入一般是標量,但NumPy中的函數可以是向量或矩陣,而利用向量或矩陣可以避免循環語句,這點在機器學習、深度學習中經常使用。以下為NumPy中的常用幾個通用函數:

1. 使用math與numpy函數性能比較

import time
import math
import numpy as np
x = [i * 0.001 for i in np.arange(1000000)]
start = time.clock()
for i, t in enumerate(x):
    x[i] = math.sin(t)
print ("math.sin:", time.clock() - start )

x = [i * 0.001 for i in np.arange(1000000)]
x = np.array(x)
start = time.clock()
np.sin(x)
print ("numpy.sin:", time.clock() - start )

列印結果:

math.sin: 0.5169950000000005
numpy.sin: 0.05381199999999886

由此可見,numpy.sin比math.sin快近10倍。

2. 使用循環與向量運算比較

充分使用Python的NumPy庫中的內建函數(built-in function),實現計算的向量化,可大大提高運行速度。NumPy庫中的內建函數使用了SIMD指令。例如下面所示在Python中使用向量化要比使用循環計算速度快得多。

import time
import numpy as np

x1 = np.random.rand(1000000)
x2 = np.random.rand(1000000)
##使用循環計算向量點積
tic = time.process_time()
dot = 0
for i in range(len(x1)):
    dot+= x1[i]*x2[i]
toc = time.process_time()
print ("dot = " + str(dot) + "\n for loop Computation time = " + str(1000*(toc - tic)) + "ms")
##使用numpy函數求點積
tic = time.process_time()
dot = 0
dot = np.dot(x1,x2)
toc = time.process_time()
print ("dot = " + str(dot) + "\n verctor version---- Computation time = " + str(1000*(toc - tic)) + "ms")

列印結果:

dot = 250215.601995
 for loop Computation time = 798.3389819999998ms
dot = 250215.601995
 verctor version---- Computation time = 1.885051999999554ms

從程序運行結果上來看,該例子使用for循環的運行時間是使用向量運算的運行時間的約400倍。因此,深度學習算法中,一般都使用向量化矩陣運算。

06 廣播機制

廣播機制(Broadcasting)的功能是為了方便不同shape的數組(NumPy庫的核心數據結構)進行數學運算。廣播提供了一種向量化數組操作的方法,以便在C中而不是在Python中進行循環,這通常會帶來更高效的算法實現。廣播的兼容原則為:

以下通過實例來具體說明。

import numpy as np
a=np.arange(10)
b=np.arange(10)
#兩個shape相同的數組相加
print(a+b)
#一個數組與標量相加
print(a+3)
#兩個向量相乘
print(a*b)

#多維數組之間的運算
c=np.arange(10).reshape([5,2])
d=np.arange(2).reshape([1,2])
#首先將d數組進行複製擴充為[5,2],如何複製請參考圖1-2,然後相加。
print(c+d)

▲圖1-2 NumPy多維數組相加

列印結果:

[ 0  2  4  6  8 10 12 14 16 18]
[ 3  4  5  6  7  8  9 10 11 12]
[ 0  1  4  9 16 25 36 49 64 81]
[[ 0  2]
 [ 2  4]
 [ 4  6]
 [ 6  8]
 [ 8 10]]

有時為了保證矩陣運算正確,我們可以使用reshape()函數來變更矩陣的維度。

07 小結

閱讀完本文,你已get到如下技能:

√ 如何生成NumPy的ndarray的幾種方式。

√ 如何存取元素。

√ 如何操作矩陣。

√ 如何合併或拆分數據。

√ NumPy的通用函數。

√ NumPy的廣播機制。

如果想進一步了解NumPy,大家可參考:

http://www.numpy.org/

關於作者:吳茂貴,BI和大數據專家,就職於中國外匯交易中心,在BI、數據挖掘與分析、數據倉庫、機器學習等領域有超過20年的工作經驗,在Spark機器學習、TensorFlow深度學習領域大量的實踐經驗。

王冬,任職於博世(中國)投資有限公司,負責Bosch企業BI及工業4.0相關大數據和數據挖掘項目。對機器學習、人工智慧有多年實踐經驗。

李濤,參與過多個人工智慧項目,如研究開發服務機器人、無人售後店等項目。熟悉python、caffe、TensorFlow等,對深度學習、尤其對計算機視覺方面有較深理解。

楊本法,高級算法工程師,在機器學習、文本挖掘、可視化等領域有多年實踐經驗。熟悉Hadoop、Spark生態圈的相關技術,對Python有豐富的實戰經驗。

本文摘編自《Python深度學習:基於TensorFlow》,經出版方授權發布。

掃碼一鍵購買

(*本文僅代表作者觀點,轉載請聯繫原作者)

「2019 Python開發者日」全日程揭曉這一次我們依然「只講技術,拒絕空談」10餘位一線Python技術專家共同打造一場硬核技術大會。更有深度培訓實操環節,為開發者們帶來更多深度實戰機會。更多詳細信息請諮詢13581782348(微信同號)。

相關焦點

  • python數據分析專題 (9):numpy基礎
    NumPy(Numerical Python的簡稱)是高性能科學計算和數據分析的基礎包。NumPy最重要的一個特點就是其N維數組對象(即ndarray),該對象是一個快速而靈活的大數據集容器。新手可能不理解這句話的含義,這個需要慢慢去理解 。總之,知道numpy是python數據分析最重要的基礎包就可以了。
  • 「AI白身境」學AI必備的python基礎
    python現在火的程度已經不需要我多言了,它為什麼為火,我認為有兩個原因,第一是人工智慧這個大背景,第二是它真的太容易學了,沒有任何一門語言比它好上手,接下來我將和大家分享下python的基礎操作。另外請注意,我的所有操作都是基於python3!
  • 資源|用Python和NumPy學習《深度學習》中的線性代數基礎
    本文系巴黎高等師範學院在讀博士 Hadrien Jean 的一篇基礎學習博客,其目的是幫助初學者/高級初學者基於深度學習和機器學習來掌握線性代數的概念。掌握這些技能可以提高你理解和應用各種數據科學算法的能力。
  • 機器學習必備Python庫之Numpy基礎學習
    關於numpy的學習內容如下:數組簡介和數組的構造數組取值和賦值數學運算broadcasting邏輯運算數組高級操作文件輸入輸出(橙色部分為代碼列印輸出的部分,所有代碼均經過實際操作所得。)導入Numpy庫import numpy  as np創建一個一維數組a=np.array([1,3,5])print(a)[1 3 5]列印變量a的類型print(type(a))
  • Python數據科學Numpy基礎20問
    1、什麼是numpy?一言以蔽之,numpy是python中基於數組對象的科學計算庫。提煉關鍵字,可以得出numpy以下三大特點:2、如何安裝numpy?因為numpy是一個python庫,所以使用python包管理工具pip或者conda都可以安裝。
  • Python自動化用這些知識點就夠了!
    python基礎能做這些的前提是會使用Python,最起碼要熟悉基本語法,可以編寫小腳本。對於python語法的要求,你可以對照python基礎教程的部分查看需要學那些,找個免費視頻教程跟著學,然後多敲代碼練習。如果習慣看書的話,可以買本python入門書備查。
  • python:numpy入門詳細教程
    python數據科學基礎庫主要是三劍客:numpy,pandas以及matplotlib,每個庫都集成了大量的方法接口,配合使用功能強大。numpy:numerical python縮寫,提供了底層基於C語言實現的數值計算庫,與python內置的list和array數據結構相比,其支持更加規範的數據類型和極其豐富的操作接口,速度也更快num
  • Python中的Numpy基礎20問
    import numpy as np# 創建二維數組x2 = np.array([[1,2,3],[4,5,6]])# 將x2轉換為三維數組,並且自定義每個軸的元素數量x2.resize((1,2,3))x2'''輸出:array([[[1, 2, 3],[4, 5, 6]]])'''如何對數組進行索引和切片操作?numpy一維數組的索引和切片操作類似python列表,這裡不多講。
  • Python冬令營-Numpy 使用簡介
    source: https://realpython.com/numpy-tutorial/#hello-numpy-curving-test-grades-tutorial聲明:本篇推送的主要內容翻譯自:https://realpython.com/numpy-tutorial/#hello-numpy-curving-test-grades-tutorial
  • 學習Python必知的Numpy函數
    有了這些擴展包,數據科學家們可以不用重複造輪子,節省了很多時間。其中一個重要的數學擴展包就是 NumPy。NumPy 是一個基礎數學包,以其高效的多維數組函數而聞名,適用於線性代數,傅立葉變換,邏輯運算等。本文從 NumPy 最基礎的知識切入,包括 NumPy 裡面的函數,如何創建 NumPy 數組,數組的索引、切片等,非常適合初學者。
  • 學習筆記,從NumPy到Scrapy,學習Python不能錯過這些庫
    在網絡上看到幾位前輩寫了關於python深度學習庫的文章,對於小小白來說,因為我剛開始學python,我得承認自己看完後依然覺得雲裡霧裡的,不知道這些庫到底對我有什麼用處。所以我到網絡上搜集補充關於這些庫的說明內容,感覺在這個整理資料的過程中,對於這些python程序庫了解了更多,以下是我整理的學習筆記。
  • 如何系統地學習Python 中 matplotlib, numpy, scipy, pandas?
    它可以向開發者提供用於數據操作與可視化的高級命令和類,是構建交互式 Python 會話的強大工具。Pandas:面向數據操作和分析的 Python 庫,提供用於處理數字圖表和時序數據的數據結構和操作功能。Matplotlib:Python 中常用的繪圖庫,能在跨平臺的交互式環境生成高質量圖形。後來在它的基礎上又衍生了更為高級的繪圖庫 Seaborn。
  • 好程式設計師Python培訓分享numpy簡介
    好程式設計師Python培訓分享numpy簡介:一、numpy簡介:NumPy是一個功能強大的Python庫,主要用於對多維數組執行計算。NumPy這個詞來源於兩個單詞-- Numerical和Python。NumPy提供了大量的庫函數和操作,可以幫助程式設計師輕鬆地進行數值計算。
  • Python之numpy數組學習(一)
    Python本身支持整型、浮點型和複數型,為了科學計算,numpy提供了更加豐富的數據類型,注意:numpy跟數學運算有關的數據類型的名稱都以數字結尾。這個數字指示了該類型的變量所佔用的二進位位數。Numpy的各種數值類型如下圖所示:
  • python數據分析:numpy入門
    微信公眾號:學點啥玩點啥小白友好型python數據分析:numpy入門numpy:一個在python中做科學計算的基礎庫,重在數值計算,也是大部分python科學計算庫的基礎庫,多用於在大型、多維數組上執行數值計算。
  • python數據科學系列:numpy入門詳細教程
    python數據科學基礎庫主要是三劍客:numpy,pandas以及matplotlib,每個庫都集成了大量的方法接口,配合使用功能強大。numpy:numerical python縮寫,提供了底層基於C語言實現的數值計算庫,與python內置的list和array數據結構相比,其支持更加規範的數據類型和極其豐富的操作接口,速度也更快numpy的兩個重要對象是
  • Python NumPy可視化圖解(上)
    同時,在PyTorch、TensorFlow、Keras等深度許欸小框架中,了解numpy將顯著提高數據共享和處理能力,甚至無需過多更改就可以在GPU運行計算。n維數組是NumPy的核心概念,這樣的好處,儘管一維和而為數組的處理方式有些差異,但多數不同維數組的操作是一樣的。
  • 【入門基礎】Numpy基礎20問
    一言以蔽之,numpy是python中基於數組對象的科學計算庫。提煉關鍵字,可以得出numpy以下三大特點:2、如何安裝numpy?因為numpy是一個python庫,所以使用python包管理工具pip或者conda都可以安裝。
  • Python | Numpy簡介
    Numpy簡介python標準庫中的列表(list)可以當數組用,支持動態內存分配和垃圾收集,列表元素可以是任何對象,功能強大!兩大法寶:多維數組ndarray和通用函數ufunc如何使用Numpy等python第三方軟體包?(如何開外掛?)被import的可以是通過conda或pip安裝的包,也可以是python的path中(包括當前目錄)的其它x.py文件。
  • python數據分析專題 (10):numpy使用
    NumPy的ndarry類型也可以進行很多操作,例如數組的索引,組合等,這次內容介紹一些關於numpy多維數組的操作。