當前位置:
首頁 > 知識 > Python:一篇文章掌握Numpy的基本用法

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

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


前言

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

本文主要內容如下:

  1. Numpy數組對象
  2. 創建ndarray數組
  3. Numpy的數值類型
  4. ndarray數組的屬性
  5. ndarray數組的切片和索引
  6. 處理數組形狀
  7. 數組的類型轉換
  8. numpy常用統計函數
  9. 數組的廣播

1 Numpy數組對象

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

  • ndarray數據本身
  • 描述數據的元數據

Numpy數組的優勢

  • Numpy數組通常是由相同種類的元素組成的,即數組中的數據項的類型一致。這樣有一個好處,由於知道數組元素的類型相同,所以能快速確定存儲數據所需空間的大小。
  • Numpy數組能夠運用向量化運算來處理整個數組,速度較快;而Python的列表則通常需要藉助循環語句遍歷列表,運行效率相對來說要差。
  • Numpy使用了優化過的C API,運算速度較快

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

  • 使用python的list進行循環遍歷運算

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

  • 使用numpy進行向量化運算

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]]])

  • 請注意:arange的長度與ndarray的維度的乘積要相等,即 24 = 2X3X4

  • 用numpy.random創建數組的方法,可以參考下面的文章

  • 為什麼你用不好Numpy的random函數?
  • 其他創建ndarray的方法,各位小夥伴們自己可以研究下。

3 Numpy的數值類型

Numpy的數值類型如下:

Python:一篇文章掌握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.])

請注意,複數不能轉換成為整數類型或者浮點數,比如下面的代碼會運行出錯

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

# float(42 + 1j)

4 ndarray數組的屬性

  • dtype屬性

    ,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)

  • ndim屬性

    ,數組維度的數量

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

2

  • shape屬性

    ,數組對象的尺度,對於矩陣,即n行m列,shape是一個元組(tuple)

a.shape

(2, 3)

  • size屬性

    用來保存元素的數量,相當於shape中nXm的值

a.size

6

  • itemsize

    屬性返回數組中各個元素所佔用的位元組數大小。

a.itemsize

4

  • nbytes屬性

    ,如果想知道整個數組所需的位元組數量,可以使用nbytes屬性。其值等於數組的size屬性值乘以itemsize屬性值。

a.nbytes

24

a.size*a.itemsize

24

  • T屬性

    ,數組轉置

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]])

  • 複數的實部和虛部屬性,real和imag屬性

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.])

  • flat屬性

    ,返回一個numpy.flatiter對象,即可迭代的對象。

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

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

f = e.flat
f


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各種屬性的一個小結

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


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:一篇文章掌握Numpy的基本用法

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


6 處理數組形狀

6.1 形狀轉換

  • reshape和resize

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的效果

  • ravel和flatten

    ,將多維數組轉換成一維數組,如下:

b.ravel

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

b.flatten

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

參考如下代碼:

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

  • 用tuple指定數組的形狀

    ,如下:

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 堆疊數組

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]])

  • concatenate方法,通過設置axis的值來設置疊加方向

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的方向經常會混淆,通過示意圖,或許可以更好的理解。

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

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

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

深度疊加

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

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)的三維數組。

深度疊加的示意圖如下:

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

6.3 數組的拆分

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

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

  • 沿橫向軸拆分(axis=1)

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]])]

  • 沿縱向軸拆分(axis=0)

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 數組的類型轉換

  • 數組轉換成list,使用tolist

b.tolist

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

  • 轉換成指定類型,astype函數

b.astype(float)

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

8 numpy常用統計函數

常用的函數如下:

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

  • np.sum,返回求和
  • np.mean,返回均值
  • np.max,返回最大值
  • np.min,返回最小值
  • np.ptp,數組沿指定軸返回最大值減去最小值,即(max-min)
  • np.std,返回標準偏差(standard deviation)
  • np.var,返回方差(variance)
  • np.cumsum,返回累加值
  • np.cumprod,返回累乘積值

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

    ,返回整個數組的最大值減去最小值,如下:

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])

  • np.cumsum

    ,沿指定軸方向進行累加

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

    ,沿指定軸方向進行累乘積 (Return the cumulative product of the elements along the given axis)

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)」

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」。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

Java集合-LinkedList
大數據平台搭建-zookeeper集群的搭建
收集一些工作中常用的經典SQL語句
BinarySearchTree-二叉搜索樹

TAG:科技優家 |

您可能感興趣

從 Zero到Hero,一文帶你完全掌握 Python
Python程序員為什麼一定要掌握Linux?
Flutter、GraphQL、PWA、WebAssembly……大前端時代,你需要掌握的那些技術
一文掌握InfiniBand技術和架構
NYPD:掌握很多關於Weinstein的關鍵證據,準備逮捕
Android 開發應該掌握的 Proguard 技巧
掌握Photoshop中的雙色調效果
以色列公司 Cellebrite 掌握 iOS 漏洞,能為任何一支 iPhone 解鎖
格拉蘇蒂原創 Glashütte Original:複雜功能至簡呈現 讓世界時間盡在掌握
一篇文章掌握Gradle多項目構建
三星推出Bixby Routines 掌握用戶習慣 你所需要的它都知道
掌握這幾招,你的照片秒變Gucci、Supreme時尚大片!
別具風格的機甲遊戲《into the breach》合理掌握你的方寸之地
ColorStudio 02期|掌握塗刷的正確姿勢,DIY不再是夢
影音娛樂一手掌握西數My Passport SSD體驗
打敗 Python、JS、C#成最受歡迎編程語言,是時候掌握 Rust 了嗎?
Integer類掌握了多少?
李起光出演《Lovely Horribly》和宋智孝合作!掌握劇中關鍵秘密
2句話,掌握how to的真正用法
掌握這幾個技巧,讓 AirPods在Android 上也一樣好用