- NumPy是Numeric Python的簡稱
- NumPy是Python科學計算的基礎工具包
- NumPy是Python數值計算擴展,專門用于處理矩陣,其運算效率比列表更高效。
- NumPy底層使用C編寫,能高效地執行數值計算。
隨著數據科學(Data Science,DS)發展,科學計算、數據處理等數據分析庫大量增長。在矩陣乘法和數組形狀處理上,NumPy具有較好的優勢。
- 數組算數、邏輯運算
- 傅里葉變換、圖形操作
- 線性代數操作
NumPy通常會與SciPy和Matplotlib繪圖庫組合使用,此組合廣泛用于替代MatLab,是一種流行的技術計算平臺。
學習資料
安裝
查看是否安裝
- NumPy作為Python的第三方擴展庫,沒有包含在標準庫中,因此需要獨立安裝。
$ pip list | grep numpy
numpy 1.20.3
numpydoc 1.1.0
$ pip install numpy
檢測安裝版本
import numpy as np
print(np.__version__)
實際項目中NumPy與SciPy會一起使用,SciPy可看作是NumPy的擴展。
ndarray
數組是元素或值的集合,可具有多個維度。通常一維數組稱為向量,二維數組稱為矩陣。
- NumPy的數據結構是
n
維的數組對象ndarray
,Python的list
雖然也能表示但不高效,隨著列表數據的增加效率會降低。 - NumPy的
ndarray
是一個由一系列相同類型的元素組成的數組集合,以0下標為開始進行集合中元素的索引。 -
ndarray
數組中的每個元素都占有大小相同的內存塊,因此可直接使用索引或切片的方式來訪問。 -
ndarray
對象采用了數組的索引機制,將數組元素映射到內存塊上,并按一定的布局對內存塊進行排列。常見的布局方式分為按行或按列。
內存結構
- 一個指向數據的指針,內存或內存映射文件中的一塊數據。
- 數據類型
dtype
,描述在數組中固定大小值的格子。 - 一個表示數組型形狀
shape
的元組,表示各個維度大小的元組。 - 一個跨度元素
stride
,整數表示為了前進到下一個元素需要跨過的字節數。跨度可以是負數,負數可以使數組在內存中向后移動,切片中obj[::-1]
或obj[:, ::-1]
即如此。
Python本身執行是慢的,因為會執行很多復雜的check功能,而調用NumPy時其實調用調用的是C語言而非Python。NumPy其實是C的邏輯,例如創建存儲容器array
是會尋找內存上一連串區域來存放,而Python存放的原則是不連續的區域。這使得Python在索引容器中的數據時不會那么高效。Numpy只需要在固定的連續區域前后游走就能拿到數據。
NumPy通常不是用一個一維數組來存放數據,而是用二維或三維的塊來存放,NumPy快速的矩陣相乘運算,能將乘法運算分配到計算機的多核上來并行運算來加速運算速度。
創建
- NumPy內置函數
array()
可創建ndarray
對象
numpy.array( object, dtype = None, copy = True, order = None, subok = False, ndim = 8)
構造參數 | 必填 | 描述 |
---|---|---|
object | 必須 | 任何暴露數組接口方法的對象都會返回一個數組或任意嵌套序列 |
dtype | 可選 | 數組所需的數據類型 |
copy | 可選 | 對象是否被復制 |
order | 可選 | 排序類型,C按行/F按列/A任意(默認)。 |
subok | 可選 | 默認返回的數組會被強制為基類數組,若subok為true則為子類。 |
ndim | 可選 | 數組的最小維度 |
例如:創建一維數組并獲取類型
import numpy as np
nda = np.array([1, 2, 3])
print(nda)
print(type(nda))
[1 2 3]
<class 'numpy.ndarray'>
例如:創建多維數組并轉化為復數類型
import numpy as np
lst = [
[1, 2, 3],
[10, 20, 30]
]
nda = np.array(lst, dtype = 'complex')
print(nda)
NumPy中主要的數據對象是具有相同數據類型的多維數組,所有元素都具有相同數據類型,通過一個正整數元素索引的元素表格,通常元素是數字。
例如:使用NumPy中的array
函數將系統自帶的列表list
轉換成為NumPy中的數組,嵌套列表會被轉換為多維數組(矩陣)。
import numpy as np
lst = [[1, 3, 5], [2, 4, 6]]
arr = np.array(lst)
array([
[1, 3, 5],
[2, 4, 6]
])
NumPy中array
數組內部的元素必須為相同類型,可使用dtype
指令查看類型。
import numpy as np
lst = [[1, 3, 5], [2, 4, 6]]
arr = np.array(lst)
arr.dtype
dtype('int32')
通常數組元素開始都是未知的,但大小已知。因此NumPy使用占位符創建數組的函數。
數據類型
NumPy支持的數據類型比Python內置的要多,基本和C語言的數據類型對應。
數據類型 | 描述 |
---|---|
bool_ |
布爾類型,值為True 或False 。 |
int_ |
模型整型,類似C中的long 、int32 、int64 。 |
intc |
類似C中的int 類型,一般為int32 或int64 。 |
intp |
用于索引的整型,類似C中的ssize_t ,一般為int32 或int64 。 |
int8 |
字節,數據范圍-127~127 。 |
int16 |
整型,數據范圍-32768~32767 。 |
int32 |
整型 |
int64 |
整型 |
uint8 |
無符號整數 |
uint16 |
無符號整數 |
uint32 |
無符號整數 |
uint64 |
無符號整數 |
float_ |
float64 類型縮寫 |
float16 |
半精度浮點數 |
float32 |
單精度浮點數 |
float64 |
雙精度浮點數 |
complex_ |
complex128 類型的簡寫,即128位復數。 |
complex64 |
復數,雙32位浮點數,實數部分和虛數部分。 |
complex128 |
復數,雙64位浮點數,實數部分和虛數部分。 |
數據類型對象dtype
-
dtype
是數據類型對象numpy.dtype
類的實例 -
dtype
用來描述與數組對應的內存區域是如何使用的
dtype
描述了數據的以下方面
- 數據的類型,比如整數、浮點數、Python對象。
- 數據的大小,比如整數使用多少個字節存儲。
- 數據的字節順序,比如大端法或小端法。
- 結構化類型下,字段的名稱、每個字段的數據類型、每個字段所取的內存塊的部分。
- 若數據類型是子數組則形狀和數據類型是什么
每個內置類型都具有唯一的字符代碼
類型代碼 | 數據類型 |
---|---|
b |
布爾類型 |
i |
有符號整型 |
u |
無符號整型 |
f |
浮點型 |
c |
復數浮點型 |
m |
時間間隔timedelta
|
M |
日期時間datetime
|
O |
Python對象 |
S |
字符串 |
a |
字節byte
|
U |
Unicode |
V |
原始類型void
|
語法結構
numpy.dtype(object, align, copy)
參數 | 描述 |
---|---|
object | 需要轉換為的數據類型對象 |
align | 填充字段是否使用類似C的結構體 |
copy | 是否復制dtype 對象,若為false 則是對內置數據類型對象的引用。 |
例如:定義結構化數據類型user
,包含字符串字段name
、整型字段id
、浮點型字段salary
,并將dtype
應用到數組對象中。
import numpy as np
dt = np.dtype([
('id', np.int8),
('name', 'S20'),
('salary', 'f4')
])
print(dt) # [('id', 'i1'), ('name', 'S20'), ('salary', '<f4')]
arr = np.array([
(1, 'alice', 4500),
(2, 'bob', 8700),
(3, 'carl', 9500)
], dtype = dt)
print(arr) # [(1, b'alice', 4500.) (2, b'bob', 8700.) (3, b'carl', 9500.)]
數據類型對象
- NumPy的數組
ndarray
,與標準Python類庫array.array
不同。它提供了比Python更更富的數據類型。
數據類型對象
數據類型對象(Data Type Object)又稱為dtype
對象,主要用來描述數組元素的數據類型、大小、字節順序等。同時也可以用來創建結構化數據。
例如:創建int64
類型的數組
import numpy as np
dto = np.dtype(np.int64)
print(dto) # int64
數據類型標識碼
- NumPy每種數據類型都具有一個唯一標識的字符碼
- 可使用數據類型標識碼創建結構化數據
import numpy as np
dto = np.dtype([('score', 'i1')])
print(dto) # [('score', 'i1')]
例如:使用數據類型標識碼
import numpy as np
dto = np.dtype([('score', 'i1')])
data = [
(10,),
(20,),
(30,)
]
a = np.array(data, dtype = dto)
print(a) # [(10,) (20,) (30,)]
print(a.dtype) # [('score', 'i1')]
print(a['score']) # [10 20 30]
例如:定義結構化數據,結構化數據使用字段的形式來描述某個對象的特征。
import numpy as np
dto = np.dtype([('name', 'S20'), ('gender', 'i1'), ('salary', 'f4')])
data = [
('alice', 1, 9000.00),
('job', 2, 6500.00),
('carl', 1, 4000.00)
]
arr = np.array(data, dtype = dto)
print(arr) # [(b'alice', 1, 9000.) (b'job', 2, 6500.) (b'carl', 1, 4000.)]
屬性
- NumPy數組的維數稱為秩
rank
,秩的數量就是軸的數量,也就是數組的維度。
比如一維數組的秩為1,二維數組的秩為2,以此類推。 - NumPy中每個線性的數組稱為一個軸Z
axis
,也就是維度dimensions
。
比如二維數組相當于兩個一維數組,第一個一維數組中的每個元素又是一個一維數組。,所以一維數組是NumPy的軸,第一個軸相當于是底層數組,第二個軸是底層數組中的數組,軸的數量有也就是秩,即數組的維數。
屬性 | 數組 | 描述 |
---|---|---|
軸 | 數組的維度 | 形狀 |
秩 | 數組的維數 | 軸的數量 |
例如:NumPy中維度(dimensions)叫做軸(axies),軸的個數稱為秩(rank)。
[1, 2, 3]
例如:3D空間中的一個點的坐標[1, 2, 3]
是一個秩為1的數組(一個維度),它只有一個軸。軸的長度為3。
[[1., 0., 0.], [0., 1., 2.]]
數組的秩為2,具有兩個維度,第一個維度長度為2,第二個維度長度為3。
屬性 | 描述 |
---|---|
ndarray.ndim | 數組的維數 |
ndarray.shape | 數組的維度,返回由數組維度構成的元組,可用來調整數組形狀。 |
ndarray.size | 數組元素總個數 |
ndarray.itemsize | 數組中每個元素的字節大小 |
ndarray.dtype | 數據中元素類型的對象 |
ndarray.data | 實際數組元素的緩沖區 |
ndarray.flags | ndarray數組內存信息 |
例如:生成3x5二維數組后獲取屬性
from numpy import *
arr = arange(15).reshape(3, 5)
print(arr)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
print(arr.ndim) # 2
print(arr.shape) # (3, 5)
print(arr.dtype.name) # int32
print(arr.itemsize) # 4
print(arr.size) # 15
print(type(arr)) # <class 'numpy.ndarray'>
維數ndim
- 獲取數組的維數,即秩
rank
。
例如:使用ndim
屬性查看數組維數
import numpy as np
lst = [
[1, 2, 3],
[10, 20, 30]
]
nda = np.array(lst, dtype = 'complex')
print(nda.ndim) # 2
例如:指定維數創建數組,報錯。
import numpy as np
lst = [1, 2, 3]
nda = np.array(lst, ndim=2)
print(nda)
TypeError: 'ndim' is an invalid keyword argument for array()
形狀shape
-
ndarray.shape
表示數組的維度,返回一個元組。 - 元素的長度也就是維度的數量,即
ndim
屬性的值(秩)。
例如:一個二維數組,其維度表示為行數和列數
import numpy as np
arr = np.array([
[1, 2, 3],
[4, 5, 6]
])
print(arr.shape) # (2, 3)
-
ndarray.shape
可用于調整數組大小
arr.shape = (3, 2)
print(arr)
[[1 2]
[3 4]
[5 6]]
- NumPy也專門提供了
reshape()
方法來調整數組的形狀,即數組變維。
數組變維rechape()
- 數組形狀是指多維數組的行數和列數,數組變維實際上是對數組形狀的重塑。
- NumPy提供了
reshape()
函數用來改變多維數組行數和列表,從而達到數組變維的目的。 -
reshape()
通常返回的是非拷貝副本,改變返回數組的元素后原數組對應元素的值也會改變。
import numpy as np
arr = np.array([[1, 2], [3, 4], [5, 6]])
ary = arr.reshape(2, 3)
print(ary)
[[1 2 3]
[4 5 6]]
元素大小itemsize
-
ndarray.itemsize
屬性會以字節形式返回數組中每個元素的大小
例如:類型為float64
的數組的itemsize
為8,因為float64
占64個bits
,每個字節長度為8,因此占8個字節。
import numpy as np
arr = np.array([1, 1.1, 2.2], dtype = np.float64)
print(arr.itemsize) # 8
內存信息flags
-
nparray.flags
屬性會返回數組對象的內存信息
例如:獲取數組內存信息
import numpy as np
arr = np.array([1, 1.1, 2.2], dtype = np.float64)
print(arr.flags)
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
內存信息 | 簡稱 | 描述 |
---|---|---|
C_CONTIGUOUS | C | 數據在一個單一的C風格的連續段上 |
F_CONTIGUOUS | F | 數據在一個單一的Fortran風格的連續段中 |
OWNDATA | O | 數組擁有它所使用的內存,或從另一個對象中借用它。 |
WRITSBLE | W | 數據區域可以被寫入,設置為False則數據為只讀。 |
ALIGNED | A | 數據和所有元素都適當對齊到硬件上 |
UPDATEIFCOPY | U | 數組是其他數組的一個副本,當數組被釋放時源數組內容將被更新。 |
方法
函數 | 描述 |
---|---|
zeros() | 創建元素全是0的數組 |
ones() | 創建元素全是1的數組 |
empty() | 創建內容隨機且以來內存狀態的數組 |
例如:
from numpy import *
print( zeros( (3,4) ) )
print( ones( (2,3,4), dtype=int16 ) )
print( empty( (2,3) ) )
創建數列
- NumPy提供了類似
arange
函數用于返回數組而非列表
from numpy import *
arange( 10, 30, 5 )
array([10, 15, 20, 25])
數組計算
- 數組計算無需循環即可批量運算
import numpy as np
lst = [[1, 3, 5], [2, 4, 6]]
arr = np.array(lst)
print(arr)
print(arr + 1)
print(arr - 1)
print(arr * 2)
print(arr * arr)
[[1 3 5]
[2 4 6]]
[[2 4 6]
[3 5 7]]
[[0 2 4]
[1 3 5]]
[[ 2 6 10]
[ 4 8 12]]
[[ 1 9 25]
[ 4 16 36]]
數組賦值
- 數組索引和列表相同,可通過方括號
[]
和數字選擇,也可直接賦值。
import numpy as np
lst = [[1, 3, 5], [2, 4, 6]]
arr = np.array(lst)
print(arr[1])
print(arr[1][1])
print(arr[-1:])
arr[0] = [10, 30, 50]
print(arr[0])
[2 4 6]
4
[[2 4 6]]
[10 30 50]
空數組empty()
NumPy提供了empty()
方法來創建一個指定形狀shape
和數據類型dtype
,但未初始化的空數組。由于未初始化,因此元素值會是隨機數。
numpy.empty(shape, dtype = float, order = 'C')
屬性 | 描述 |
---|---|
shape |
數組形狀 |
dtype |
數據類型,可選。 |
order |
內存中存儲元素的順序,C表示行優先,F表示列優先。 |
排序 | 描述 |
---|---|
C | 行優先,用于C的行數組。 |
F | 列優先,用于Fortan的列數組。 |
例如:創建一個2行3列的二維空數組
import numpy as np
arr = np.empty([2, 3], dtype = int)
print(arr)
[
[ 0 1072693248 -1717986918]
[ 1072798105 -1717986918 1073846681]
]
零數組zeros()
NumPy提供的zeros()
方法可用來創建指定形狀的且使用0填充的數組
numpy.zeros(shape, dtype = float, order = 'C')
屬性 | 描述 |
---|---|
shape | 數組形狀 |
dtype | 數據類型,可選。 |
order | 內存存儲元素的排序方式 |
import numpy as np
arr = np.zeros(3)
print(arr) # [0. 0. 0.]
arr = np.zeros((3,), dtype = np.int32)
print(arr) # [0 0 0]
arr = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'f4')])
print(arr)
[
[(0, 0.) (0, 0.)]
[(0, 0.) (0, 0.)]
]
壹數組ones()
NumPy提供的ones()
方法用于創建指定形狀且元素以1來填充的數組
numpy.ones(shape, dtype = None, order = 'C')
例如:
import numpy as np
arr = np.ones(3)
print(arr) # [1. 1. 1.]
arr = np.ones((3,), dtype = np.int32)
print(arr) # [1 1 1]
arr = np.ones((2,2), dtype = [('x', 'i4'), ('y', 'f4')])
print(arr)
[
[(1, 1.) (1, 1.)]
[(1, 1.) (1, 1.)]
]
區間數組
區間數組是指數組元素的取值位于某個范圍內,元素之間呈現出某種規律,比如等比、遞增、遞減等。
區間數組 | 描述 |
---|---|
numpy.arange() | 生成普通數列 |
numpy.linspace() | 生成等差數列 |
numpy.logspace() | 生成等比數列 |
numpy.arange()
函數可根據start
開始和stop
結束指定的范圍,以及step
步長來生成一個ndarray
的數組。
numpy.arange(start, stop, step, dtype)
參數 | 描述 |
---|---|
start | 起始值,默認為0。 |
stop | 終止值,生成的ndarray 中的元素不包含終止值。 |
step | 步長,默認為1。 |
dtype | 可選,指定生成ndarray 的數據類型。 |
例如:生成自然序列
import numpy as np
dn = np.arange(1, 10, 1)
print(dn) # [1 2 3 4 5 6 7 8 9]
numpy.linspace()
函數用于在指定的數值區間內返回均勻間隔的一維等差數組,默認均分為50份。
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
參數 | 描述 |
---|---|
start | 數值區間起始值 |
stop | 數值區間終止值 |
num | 數值區間生成均勻樣本數量,默認50份。 |
endpoint | 生成的數列是否stop終止值 |
retstep | 生成的數列中是否顯示公差項 |
dtype | 生成的數列元素的數據類型 |
例如:生成1~10之間公差為0.25的等分數列
import numpy as np
dn = np.linspace(1, 10, 5, endpoint=True)
print(dn) # [ 1. 3.25 5.5 7.75 10. ]
numpy.logspace()
函數用于創建等比數列
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
參數 | 描述 |
---|---|
start | 序列起始值 |
stop | 序列終止值 |
num | 數值范圍區間內樣本數量 |
endpoint | 結果數列是否包含終止值 |
base | 對數函數的log 底數,默認為10。 |
dtype | 可選,結果數列元素的數據類型。 |
例如:順序生成以2作為底數,10個等比數列。
import numpy as np
dn = np.logspace(1, 10, num=10, base=2)
print(dn) # [ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
索引切片
若要訪問或修改數組中的元素,可采用索引或切片的方式。默認數組索引從0開始,可使用下標索引依次訪問數組中的元素。類似Python中的list
列表。
NumPy提供多種類型的索引方式,常見包括基本切片和高級索引。
基本切片
NumPy內置的slice()
函數可用來構造切片對象,實現從原始數組上切割出一個新數組。
numpy.slice(start, stop, step)
參數 | 描述 |
---|---|
start | 起始索引 |
stop | 終止索引 |
step | 步長 |
例如:從0~9的自然序列中獲取4~7的新數組
import numpy as np
a = np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
s = slice(4, 8, 1)
r = a[s]
print(r) # [4 5 6 7]
基本切片除了使用slice()
函數外,還可以直接使用冒號:
來分割切片。
import numpy as np
a = np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
r = a[4:8:1]
print(r) # [4 5 6 7]
冒號切片
- 若僅輸入一個“數字”則返回與索引對應的元素,也就是通過下標索引訪問元素。
- 所采用“冒號+終止索引”方式則會獲取索引 0 到 終止索引之間的元素,不包括終止索引。
- 若采用“起始索引+冒號”方式則會返回起始索引到終止索引之間的元素
- 所采用“起始索引+終止索引”方式則返回返回兩個索引之間的所有元素,不包括終止索引。
例如:
import numpy as np
a = np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
print(a[5]) # 5
print(a[6:]) # [6 7 8 9]
print(a[:3]) # [0 1 2]
print(a[4:8]) # [4 5 6 7]
多維數組切片
import numpy as np
a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print(a)
print(a[1]) # [4 5 6]
print(a[2:]) # [[7 8 9]]
print(a[:2]) # [[1 2 3] [4 5 6]]
print(a[1:2]) # [[4 5 6]]
多維數組切片中可使用省略號...
,若在行位置使用則返回包含所有行元素,反之則包含所有列元素。
import numpy as np
a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print(a[..., 1]) # [2 5 8]
print(a[1, ...]) # [4 5 6]
print(a[..., 1:])
[[2 3]
[5 6]
[8 9]]
高級索引
高級索引會返回數組的副本(深拷貝),切片操作返回的只是數組視圖(淺拷貝)。
整數數組索引
整數數組索引可選擇數組中任意一個元素
import numpy as np
a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print(a[[0,1], [2, 1]]) # [3 5]
行索引[0,1]
,列索引[2,1]
,行列組合后得到(0,2)
、(1,1)
,(0,2)
對應的元素為3, (1,1)
對應的元素為5。
廣播機制
若兩個數組的維數不同,則元素到元素的操作是禁止的。NumPy的廣播可將較小的數組廣播到較大數組大小,以便形狀兼容。
NumPy中的廣播機制(Broadcast)旨在解決不同形狀數組之間的算數運算問題,形狀運算的前提是必須保證一致。
例如:
import numpy as np
a = np.array([
[0, 2],
[4, 6],
])
b = np.array([
[1, 3],
[5, 7]
])
c = a * b
print(c)
[
[ 0 6]
[20 42]
]
針對不同形狀的數組進行算術運算,為了保證形狀一致,NumPy設計了一種廣播機制,其核心是對形狀較小的數組,在橫向或縱向上進行一定次數的重復,使其與形狀較大的數組擁有相同的維度。因此,當不同形狀的數組運算時會自動出發廣播機制。
import numpy as np
a = np.array([
[0, 2],
])
b = np.array([
[1, 3],
[5, 7]
])
c = a * b
print(c)
[
[ 0 6]
[ 0 14]
]
數組迭代
NumPy提供了一個nditer
迭代器對象,配合for
循環可實現對數組元素的遍歷。
例如:生成4x5共20個元素數組,使用nditer
生成迭代器對象。
import numpy as np
a = np.arange(0, 100, 5)
print(a)
a = a.reshape(4, 5)
print(a)
for i in np.nditer(a):
print(i)
NumPy數組提供了兩種存儲方式,分別是C-order行優先順序和Fortrant-order列優先順序,nditer
迭代器對于特定存儲順序的數組會選擇一種與數組內存布局一致的順序,以提升數據的訪問效率。因此遍歷數組元素時,默認是無需考慮數組的存儲順序的。
例如:遍歷數組的轉置數組
import numpy as np
a = np.arange(0, 100, 5)
print(a)
a = a.reshape(4, 5)
print(a)
b = a.T # 獲取轉置數組
print(b)
for i in np.nditer(b):
print(i, end=",")
數組與轉置數組遍歷順序是一樣的,也就是說它們在內存中的存儲順序是一樣的。
例如:以C樣式訪問轉置數組的副本
import numpy as np
a = np.arange(0, 100, 5)
a = a.reshape(4, 5)
print(a)
[
[ 0 5 10 15 20]
[25 30 35 40 45]
[50 55 60 65 70]
[75 80 85 90 95]
]
可通過nditer
對象的order
參數來指定數組的遍歷順序
for i in np.nditer(a, order="C"):
print(i, end=",")
0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,
for i in np.nditer(a, order="F"):
print(i, end=",")
0,25,50,75,5,30,55,80,10,35,60,85,15,40,65,90,20,45,70,95,
nditer
對象提供了一個可選參數op_flags
讀寫模式,表示能否在遍歷數組時對元素進行修改。
讀寫模式 | 描述 |
---|---|
readonly | 只讀模式,遍歷時禁止修改元素。 |
writeonly | 只寫模式,遍歷時允許修改元素。 |
readwrite | 讀寫模式,遍歷時允許修改元素。 |
例如:
import numpy as np
a = np.arange(0, 100, 5)
a = a.reshape(4, 5)
for i in np.nditer(a, op_flags=["readwrite"]):
i[...] = 10 * i
print(i, end=",")
0,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,
nditer
對象的構造函數具有一個flags
參數,可用于外部循環時使用。
flags | 描述 |
---|---|
c_index | 跟蹤C順序的索引 |
f_index | 跟蹤Fortran順序的索引 |
multi_index | 每次迭代都會跟蹤一種索引類型 |
external_loop | 返回的遍歷結果是具有多個值的一維數組 |
廣播迭代 - 迭代多個數組
若兩個數組都能夠被廣播,nditer
對象可同時對其進行迭代。
例如:數組1的維度是3x4,數組2的維度是1x4,同時迭代后,維度小的可以被廣播到維度大的中。
數組操作
- 數組變維
- 數組轉置
- 修改維度
- 連接分割
- 增刪改查
數組變維
變維 | 描述 |
---|---|
numpy.reshape() | 不改變數組元素的前提下,修改數組的形狀。 |
numpy.ndarray.flat | 返回一個迭代器,可用for循環遍歷其中每個元素。 |
numpy.ndarray.flatten() | 以一維數組的形式返回一份數組的副本,對副本操作不影響原數組。 |
numpy.reval() | 將多維數組中的元素以一維數組的形式展開,返回數組的視圖。修改會影響原始數組。 |
例如:numpy.ndarray.flat
返回數組迭代器,結合for
來遍歷元素。
import numpy as np
a = np.arange(9).reshape(3,3)
for i in a.flat:
print(i, end=",")
例如:numpy.ndarray.flatten()
函數將返回一份數組副本,對副本修改不會影響原始數組。
import numpy as np
a = np.arange(9).reshape(3,3)
b = a.flatten(order = "F")
print(b) # [0 3 6 1 4 7 2 5 8]
例如:numpy.ravel()
函數將多維數組中元素以一維數組的形式展開,返回數組視圖,修改視圖將直接影響到原數組。
import numpy as np
a = np.arange(9).reshape(3,3)
b = a.ravel(order = "F")
print(b) # [0 3 6 1 4 7 2 5 8]
數組轉置
轉置 | 描述 |
---|---|
numpy.transpose() | 將數組維度對換 |
numpy.T | 將數組維度對換,transpose語法糖。 |
numpy.rollaxis() | 沿指定軸向后滾動至特定位置 |
numpy.swapaxes() | 數組軸對換 |
numpy.transpose(arr, axes)
參數 | 描述 |
---|---|
arr | 待操作的數組 |
axes | 可選,元素或整型數列,按照此參數進行轉置。 |
例如:將3x4轉置為4x3
import numpy as np
a = np.arange(12).reshape(3,4)
# b = np.transpose(a)
b = a.T
print(a)
print(b)
numpy.rollaxis(arr, axis, start)
參數 | 描述 |
---|---|
arr | 傳入的數組 |
axis | 沿著哪條軸向后滾動,其它軸的相對位置不變。 |
start | 默認以0軸開始,可根據數組維度調整值。 |
numpy.swapaxws(arr, axis1, axis2)
參數 | 描述 |
---|---|
arr | 傳入的數組 |
axis1 | 待交換的軸1 |
axis2 | 待交換的軸2 |
修改維度
修改維度 | 描述 |
---|---|
numpy.broadcast() | 返回數組被廣播后的對象 |
numpy.broadcast_to() | 將數組廣播為新的形式 |
numpy.expand_dims() | 擴展數組的形狀 |
numpy.squeeze() | 從數組的形狀中刪除一維項 |
numpy.broadcast()
的返回值是數組被廣播后的對象,入參為兩個數組。
數組連接
數組連接 | 描述 |
---|---|
numpy.concatenate() | 沿指定軸連接相同形狀的多個數組 |
numpy.stack() | 沿著新的軸連接一系列數組 |
numpy.hstack() | 沿水平順序堆疊序列中的數組(列方向) |
numpy.vstack() | 沿垂直方向堆疊序列中的數組(行方向) |
numpy.concatenate((arr1, arr2, ...), axis)
參數 | 描述 |
---|---|
arr1,arr2,... | 表示一些列相同類型的數組 |
axis | 沿著該參數指定的軸連接數組,默認為0。 |
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[10, 20], [30, 40]])
默認axis為0表示沿著垂直方向連接,注意數組形狀必須一致。
c = np.concatenate((a,b))
print(c)
[
[ 1 2]
[ 3 4]
[10 20]
[30 40]
]
當axis為1時表示沿著水平方向連接,注意數組形狀必須一致。
d = np.concatenate((a,b), axis=1)
print(d)
[
[ 1 2 10 20]
[ 3 4 30 40]
]
數組分割
函數 | 描述 |
---|---|
ndarray.split() | 將一個數組分割為多個子數組 |
ndarray.hsplit() | 將一個數組水平按列分割為多個子數組 |
ndarray.vsplit() | 將一個數組垂直按行分割為多個子數組 |
ndarray.split()
會沿著指定的軸將數組分割為多個子數組
ndarray.split(ary, indices_or_sections, axis)
參數 | 描述 |
---|---|
arr | 待分割的數組 |
indices_or_sections | 若為整數表示用該整數平均切分,若為數組則為沿軸切分的位置(左開右閉)。 |
axis | 為0表示橫向切分,為1表示縱向切分。 |
import numpy as np
a = np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
b = np.split(a, 2)
print(b) # [array([0, 1, 2, 3, 4]), array([5, 6, 7, 8, 9])]
c = np.split(a, [3,6])
print(c) # [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8, 9])]
增刪改查
增刪改查 | 描述 |
---|---|
numpy.resize() | 獲取指定形狀的新數組 |
numpy.append() | 將元素值添加到數組末尾 |
numpy.insert() | 沿規定軸將元素值插入到指定元素前 |
numpy.delete() | 刪除某個軸上的子數組,同時返回刪除后的新數組。 |
numpy.argwhere() | 獲取數組內符合條件的元素的索引 |
numpy.unique() | 刪除數組中重復元素,并按元素值從大到小排列,返回新數組。 |
numpy.resize(arr, shape)
- resize用于獲取指定形狀的新數組
例如:
import numpy as np
a = np.arange(10)
print(a.shape) # (10,)
b = np.resize(a, (2,2))
print(b)
[
[0 1]
[2 3]
]
numpy.append(arr, values, axis=None)
- append用于在數組末尾添加值,同時返回新數組。
參數 | 描述 |
---|---|
arr | 輸入數組 |
values | 向輸入數組中添加值,需和arr形狀保持一致。 |
axis | 為None返回一維數組,為0列不變追到行。為1行不變追加到列。 |
import numpy as np
a = np.arange(6).reshape(2,3)
追加到末尾,返回一維數組。
b = np.append(a, [10])
print(b) # [ 0 1 2 3 4 5 10]
列不變追加到行
b = np.append(a, [[10, 20, 30]], axis = 0)
print(b)
[
[ 0 1 2]
[ 3 4 5]
[10 20 30]
]
行不變追加到列
b = np.append(a, [[10], [20]], axis = 1)
print(b)
[
[ 0 1 2 10]
[ 3 4 5 20]
]
numpy.insert(arr, idx, values, axis)
- insert用于沿著指定的軸,在給定索引值的前一個位置插入值。若未指定軸則輸入數組會被展開為一維數組。
參數 | 描述 |
---|---|
arr | 輸入的數組 |
idx | 索引值,在該值之前插入values值。 |
values | 要插入的值 |
axis | 指定的軸,若無則輸入數組會被展開為一維數組。 |
import numpy as np
a = np.arange(6).reshape(2,3)
b = np.insert(a, 3, [10, 20, 30])
print(b)
[ 0 1 2 10 20 30 3 4 5]
沿著垂直方向插入
b = np.insert(a, 1, [10], axis = 0)
print(b)
[
[ 0 1 2]
[10 10 10]
[ 3 4 5]
]
沿著水平方向插入
b = np.insert(a, 1, [10], axis = 1)
print(b)
[
[ 0 10 1 2]
[ 3 10 4 5]
]
-
numpy.delete()
函數用于從輸入數組中刪除指定的子數組,并返回一個新數組。 -
numpy.delete()
函數與insert()
函數相似,若無axis
參數則輸入數組會被展開為一維數組。
numpy.delete(arr, obj, axis)
參數 | 描述 |
---|---|
arr | 輸入數組 |
obj | 整數或整數數組,表示要被刪除數組元素或子數組。 |
axis | 沿著那條軸刪除子數組 |
例如:刪除值為1的元素
import numpy as np
a = np.arange(6).reshape(3,2)
b = np.delete(a, 1)
print(b) # [0 2 3 4 5]
沿著橫軸刪除下標為1的一行
b = np.delete(a, 1, axis=0)
print(b)
[
[0 1]
[4 5]
]
沿著縱軸刪除下標為1的一列
b = np.delete(a, 1, axis=1)
print(b)
[
[0]
[2]
[4]
]
numpy.argwhere
-
numpy.argwhere()
函數返回數組中非0元素的索引 - 多維數組會返回行列索引組成的索引坐標
例如:
import numpy as np
a = np.arange(6)
b = np.argwhere(a > 1)
print(b)
[
[2]
[3]
[4]
[5]
]
多維數組返回行列索引坐標
a = np.arange(6).reshape(2,3)
b = np.argwhere(a > 1)
print(b)
[
[0 2]
[1 0]
[1 1]
[1 2]
]
numpy.unique
-
numpy.unique()
函數用于刪除數組中重復的元素
numpy.unique(arr, return_index, return_inverse, return_counts)
參數 | 描述 |
---|---|
arr | 輸入數組,多維數組則以一維數組的形式展開。 |
return_index | 返回新數組元素在原數組中的索引位置 |
return_inverse | 返回原數組元素在新數組中的索引位置 |
return_counts | 返回去重后的數組在原數組中出現的次數 |
import numpy as np
a = np.array([3,2,1,2,1,5])
b = np.unique(a)
print(b) # [1 2 3 5]
返回原數組元素在新數組中的索引位置
b = np.unique(a, return_index=True)
print(b)
(array([1, 2, 3, 5]), array([2, 1, 0, 5], dtype=int64))
返回原數組元素在新數組中的索引位置
b = np.unique(a, return_inverse=True)
print(b)
(array([1, 2, 3, 5]), array([2, 1, 0, 1, 0, 3], dtype=int64))
返回去重后的數組在原數組中出現的次數
b = np.unique(a, return_counts=True)
print(b)
(array([1, 2, 3, 5]), array([2, 2, 1, 1], dtype=int64))
位運算
位運算符 | 函數 | 描述 |
---|---|---|
& | numpy.bitwise_and() | 計算數組之間按位與運算的結果 |
| | numpy.bitwise_or() | 計算數組之間按位或運算的結果 |
~ | numpy.invert() | 計算元素之間按位取反運算的結果 |
<< | numpy.left_shift() | 將二進制數的位數向左移動 |
>> | numpy.right_shift() | 將二進制數的位數向右移動 |
按位與
- 若兩個二進制數對應位均為1則按位與運算后,該位的結果位1。
- 若兩個二進制數對應位均為0則按位與運算后,該位的結果位0。
- 若兩個二進制數對應位均為1或0則按位與運算后,該位的結果位0。
A | B | AND(A,B) |
---|---|---|
1 | 1 | 1 |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
例如:十進制10和12按位與運算后為十進制的8,即二進制1000。
import numpy as np
a,b = 10,12
print(bin(a), bin(b), np.bitwise_and(a,b)) # 0b1010 0b1100 8
1010 & 1100 = 1000
按位或bitwise_or()
- 按位或運算后只要對應二進制位上有一個為1,則運算結果為1,否則為0。
A|B|A|B
-|-|-
1|1|1
0|0|0
1|0|1
0|1|1
按位取反invert()
- 按位取反會對數組中整數按位取反,即0變1,1變0。
- 有符號的負整數時會取二進制補碼,并執行+1操作。
- 有符號二進制最高位為0時表示正數,最高位為1時表示負數。
可通過numpy.binary_repr()
函數來設置二進制數的位數
import numpy as np
a = np.array([10, 20, 30], dtype=np.uint8)
print(a, np.binary_repr(10)) # [10 20 30] 1010
print(np.invert(a)) # [245 235 225]
按位左移
-
numpy.left_shift()
函數會將數組的二進制數向左移動到指定位置,同時返回對應的二進制數。
import numpy as np
print(np.left_shift(1, 2)) # 4
--
按位右移
-
right_shift()
函數會將數組中元素的二進制向右移動到指定位置 -
right_shift()
函數的返回值對應的是二進制
import numpy as np
print(np.binary_repr(2, width=2))
print(np.right_shift(2, 2))