Python(2) -numpy 的常規函數
參考:
https://www.runoob.com/numpy/numpy-terating-over-array.html
0、初始化構造
numpy中的ndarray“看起來”可以存放不同類型的數據,不過正常業務使用中一般存放同類型的數據用于計算。
之所以說“看起來”,是因為如果其中傳進來了不同的類型,則統一視為同一類型,優先級:str > float > int
而且如果ndarray中存放字符串,所有字符串占用空間大小都相同,構建的時候以最長字符串的長度為準,短的字符串則補0。賦值的時候超過長度會截斷。
import numpy as np
np.ndim #維度
## 使用列表或元組創建
np.array([[1, 2], [3, 4], (5, 6)])
np.array([-1,5.6,4],dtype="int") #初始化時,定義其類型,不同類型會轉換。
## 使用方法創建
# 生成指定維度的全1數組
np.ones(shape)
# 生成指定維度的全0數組
np.zeros(shape)
# 生成指定維度的全為單一指定值的數組
np.full(shape, val)
# 生成n*m的矩陣,且對角線為1,其余為0
np.eye(n,m)
# 根據數組a的形狀生成全1數組
np.ones_like(a)
# 依據數組a的形狀生成全0數組
np.zeros_like(a)
# 依據數組a的形狀生成全為單一指定值的數組
np.full_like(a, val)
''' 數組的維度變換 '''
# 返回重新指定shape的數組,原數組不變
.reshape(shape)
# 同.reshape(),但改變原數組
.resize(shape)
''' 數據類型轉化 '''
# 將數組轉化為列表
.tolist()
# 轉換為其他數據類型,原數組不變
.astype(new_type)
#np.arange(12) # 0~12
#np.arange(12).reshape(3,4) # 一個3*4的2維數據
#從迭代器構建
obj = {"name":8,"age":23,"money":89}
x = np.fromiter(obj.values(),dtype="S20") #S20表示定長20的字符串。
print(x)
output>>[b'8' b'23' b'89']
常用的一些屬性
ndim 矩陣的秩
dtype矩陣的類型
itemsize 每個元素的大小
flags 對象的內存信息
數據類型:
bool_
int_ 默認整型
intc 與 C 的 int 類型一樣,一般是 int32 或 int 64
intp 用于索引的整數類型(類似于 C 的 ssize_t,一般情況下仍然是 int32 或 int64
int8 亦寫作 i1
int16 亦寫作 i2
int32 亦寫作 i4
int64 亦寫作 i8
uint8 亦寫作 u1
uint16 亦寫作 u2
uint32 亦寫作 u3
uint64 亦寫作 u4
float_ 亦寫作 f8 |
float16 亦寫作 f2
float32 亦寫作 f4
float64 亦寫作 f8
complex_
complex64
complex128
1、數組的切片
0、給定數組
import numpy as np
x1 = np.arange(6) # 一維數據
output >> [ 0 1 2 3 4 5 ]
x2 = np.arange(12).reshape(3,4) # 一個3*4的2維數據
output >>
[[0 1 2 3]
[4 5 6 7]
[8 9 10 11]]
1、一維數組普通切片
print(x1[2:5])
#output >>
[2 3 4]
print(x1[1:6:2])
#start-1, end-6, gap-2
#output >>
[1 3 5]
2、二維數組切片
print(x2[1])
print(x2[1,...])# 三個點表示該維度全部選擇
print(x2[1,])
#以上三個相同,都輸出第二行
output >>
[4 5 6 7]
print(x2[...,1]) #輸出第二列
#這里不能用x2[,1]
#output >>
[1 5 9]
print(x2[...,1:3]) #輸出第二 三列
output >>
[[1 2]
[5 6]
[9 10]]
通過row和col的索引,將數據輸出到一個數組中:
print(x2[[1,2,1,0,0,2,1],[2,3,0,1,2,3,0]]) //展示一組數據,行的idx在前,列的idx在后
output >>
[ 6 11 4 1 2 11 4]
以上的輸出是一個一維數組,如果想輸出為二維數組,可以:
rows = np.array([[0,0,1,2,1,1,0],[2,1,1,0,1,2,0]])
cols = np.array([[0,2,3,1,1,2,0],[1,3,2,0,0,0,2]])
print(x2[rows,cols])
output >>
[[0 2 7 9 5 6 0]
[9 7 6 0 4 8 2]]
以上2個是離散輸出,如果需要連續輸出:
print(x2[0:2,1:4]) #從行0~1,從列1~3,連續截取
output >>
[[1 2 3]
[5 6 7]]
print(x2[0:2,[1,3]]) #從行0~1連續截取,列1和3離散截取
output >>
[[1 3]
[5 7]]
布爾索引
print(x2[x2>5])#輸出大于5的元素,輸出為一個一維數組
output>>
[ 6 7 8 9 10 11]
nan的判斷索引:

2、數組廣播
一般情況下同shape的數組,可以直接做一些運算,如 + - * /。
廣播(Broadcast)是 numpy 對不同形狀(shape)的數組進行數值計算的方式, 對數組的算術運算通常在相應的元素上進行。
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a + b)
output >>
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
b = np.array([[0],[1],[2],[5]])
print(a + b)
output >>
[[ 0 0 0]
[11 11 11]
[22 22 22]
[35 35 35]]
注意,廣播的時候,小數組的維度必須有一個是1,小數組必須匹配大數組的對飲維度的長度。否則不會廣播
3、數組迭代 nditer
1、普通打印
import numpy as np
a = np.arange(6).reshape(2,3)
#output >>
# [[0,1,2],
# [3,4,5]
# ]
for x in np.nditer(a):
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a,order="F"): #F表是Fortran,列序優先
print (x, end=", " )
print ('\n')
#0, 3, 1, 4, 2, 5,
for x in np.nditer(a,order="C"): #C表是C語言order,行序優先,默認就是這個
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a.T): #轉置其實依然共享的同一段內存,并不會copy新內存
print (x, end=", " )
print ('\n')
#0, 1, 2, 3, 4, 5,
for x in np.nditer(a.T.copy()):#轉置的拷貝是新內存
print (x, end=", " )
print ('\n')
#0, 3, 1, 4, 2, 5,
2、可修改
默認情況下nditer是只讀的,如果需要修改,則需要設置op_flags=['readwrite'],如下:
import numpy as np
a = np.arange(6).reshape(2,3)
for x in np.nditer(a,op_flags=['readwrite']):
x[...]= x*2; # 這里的...是必須的,不過沒太理解什么意思。這里的x的類型居然是<class 'numpy.ndarray'>,具體看下面文字解釋。
print (a)
output>>
[[ 0 2 4]
[ 6 8 10]]
3、ndarray中的nditer遍歷出來的數據,為什么依然是ndarray類型,而不某一個值類型
numpy.nditer 是 NumPy 中的一個功能強大的迭代器,用于遍歷多維數組的元素。當你使用 nditer 遍歷數組時,雖然你實際上是在逐個訪問數組的元素,但這些元素在被訪問時仍然保持為 NumPy 的 ndarray 類型。這是因為在 nditer 的設計上,它返回的是指向數組內部元素的指針,而不是直接的值。
舉個例子,如果你有一個一維數組 a = np.array([1, 2, 3]),使用 nditer 遍歷它時,雖然每個迭代步驟返回的是單個整數,但這些整數實際上是數組 a 中對應位置的值,因此它們仍然是 ndarray 類型。
這里的關鍵是,nditer 返回的是元素的值,而不是元素本身。在 Python 中,整數、浮點數等基本數據類型是不可變的,因此當你從 nditer 獲取一個值時,這個值實際上是一個指向原始數組中相應位置的引用,而不是一個新的、獨立的對象。
如果你想獲取每個元素的值而不是 ndarray 對象,你可以在遍歷過程中將元素轉換為其他類型,例如將整數轉換為字符串。這樣,每個元素都會被轉換為一個新的對象(在這個例子中是字符串),而不是原始數組的引用。
總結一下,nditer 返回的元素仍然是 ndarray 類型,是因為它返回的是指向數組內部元素的指針,而不是元素本身的副本。如果你希望獲得元素的副本(例如將整數轉換為字符串),你需要手動進行轉換。
4、使用外部循環
flags = ['external_loop']
當設置 flag 為 external_loop 時,numpy.nditer 將只遍歷數組的最外層維度,而忽略內部維度。
具體用法:
import numpy as np
a = np.arange(0,12)
a = a.reshape(3,4)
print ('原始數組是:')
print (a)
print ('\n')
print ('修改后的數組是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'C'):
print (x, end=", " )
print("mydiv")
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", " )
print("mydiv")
output>>
原始數組是:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
修改后的數組是:
[ 0 1 2 3 4 5 6 7 8 9 10 11], mydiv
[0 4 8], mydiv
[1 5 9], mydiv
[ 2 6 10], mydiv
[ 3 7 11], mydiv
這個比較難理解。根據代碼理解:
對于【上述order="C"的情景】,將非外部數據看做一個整體,一次性輸出。只有遍歷完后才觸及最外層的維度末尾。
對于上述order="F",由于豎著打印,所以每次都會初級外層維度的末尾,因此打印了4次。
4、數組的元素迭代器
之前的nditer迭代器中的內容是數組。flat迭代器中的內容就是元素本身。
import numpy as np
#每行打印
a = np.arange(9).reshape(3,3)
print ('原始數組:')
for row in a:
#print(type(row)) #這里的類型是ndarray,跟nditer一樣的類型
print (row) #[0 1 2 ] [。。。。]......
'''
[[0 1 2]
[ 3 4 5]
[ 6 7 8]]
'''
#flat 獲取元素迭代器
print ('迭代后的數組:')
for element in a.flat:
#print(type(element)) #這里的類型是int類型,也就是元素的類型
print (element) #0 1 2 3.........
#flatten 獲取一個平鋪數組。返回一個新數組,不影響原數組
b = a.flatten()
print(b) #[0 1 2 3 4 5 6 7 8 ]
b = a.flatten(order="F")
print(b) #[0 3 6 1 4 7 2 5 8]
#ravel 獲取一個平鋪數組,跟flatten差不多。返回引用,如果修改了返回的數組,那么原數組也會同步修改
b = a.ravel()
print(b)
#b[0] = 100 #如果修改了b[0],那么a[0][0]也會被修改。
#print(a)
5、數組的其他操作
(1)翻轉
import numpy as np
a = np.arange(12).reshape(3,4)
print(a)
'''
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
'''
#transpose 翻轉
b=np.transpose(a) #返回的是一個引用,不是復制體
#b = a.T #用T也是一樣的效果
print (b)
'''
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
'''
(2)rollaxis滾動軸
a = np.arange(24).reshape(2,3,4)
print(a)
'''
[[[ 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 = np.rollaxis(a,2,start=0) #第二個參數表示要滾動的軸,第三個參數表示將該軸滾動到的位置 默認0。
print(b)
# 將原來的最后一個維度變成了第一個維度。
'''
[[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
'''
(3)swapaxes交換軸
a = np.arange(24).reshape(2,3,4)
print(a)
'''
[[[ 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 = np.swapaxes(a,1,2)
print(b)
# 將1 2 的兩個維度交換。
'''
[[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]]]
'''
(4)廣播
a = np.arange(4).reshape(1,4)
'''
[[0 1 2 3]]
'''
print (np.broadcast_to(a,(4,4))) #維度必須匹配,才能自動廣播
'''
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
'''
(5)維度拓展/刪除
expand_dims(arr, axis)
a = np.arange(6).reshape(2,3)
b = np.expand_dims(a,0)#在0軸增加一個維度
print(b)
'''
[[[0 1 2]
[3 4 5]]]
'''
squeeze(arr, axis)
a = np.arange(24).reshape(1,2,3,4)
'''
[[[[ 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 = np.squeeze(a,0)#將0軸刪除,這個必須是一維條目
print(b)
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
6、數組的連接
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('沿軸 0 連接兩個數組:')
print (np.concatenate((a,b)))
print ('沿軸 1 連接兩個數組:')
print (np.concatenate((a,b),axis = 1))
沿軸 0 連接兩個數組:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿軸 1 連接兩個數組:
[[1 2 5 6]
[3 4 7 8]]
除了,concatenate外,還有stack hstack vstack等函數,可以用來堆疊。
7、數組的切割
a = np.arange(9)
>> [0 1 2 3 4 5 6 7 8]
print ('將數組分為三個大小相等的子數組:')
b = np.split(a,3)
>> [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
print ('將數組在一維數組中表明的位置分割:')
b = np.split(a,[4,7])
>> [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
除了split外,還有hsplit和vsplit。
8、數組的插入刪除
append
a = np.array([[1,2,3],[4,5,6]])
print ('第一個數組:')
print (a)
print ('\n')
print ('向數組添加元素:')
print (np.append(a, [7,8,9]))
print ('\n')
print ('沿軸 0 添加元素:')
print (np.append(a, [[7,8,9]],axis = 0))
print ('\n')
print ('沿軸 1 添加元素:')
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
第一個數組:
[[1 2 3]
[4 5 6]]
向數組添加元素:
[1 2 3 4 5 6 7 8 9]
沿軸 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]
沿軸 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]
insert
a = np.array([[1,2],[3,4],[5,6]])
print ('第一個數組:')
print (a)
print ('\n')
print ('未傳遞 Axis 參數。 在刪除之前輸入數組會被展開。')
print (np.insert(a,3,[11,12]))
print ('\n')
print ('傳遞了 Axis 參數。 會廣播值數組來配輸入數組。')
print ('沿軸 0 廣播:')
print (np.insert(a,1,[11],axis = 0))
print ('\n')
print ('沿軸 1 廣播:')
print (np.insert(a,1,11,axis = 1))
第一個數組:
[[1 2]
[3 4]
[5 6]]
未傳遞 Axis 參數。 在刪除之前輸入數組會被展開。
[ 1 2 3 11 12 4 5 6]
傳遞了 Axis 參數。 會廣播值數組來配輸入數組。
沿軸 0 廣播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿軸 1 廣播:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
delete
刪除操作類似:
Numpy.delete(arr, obj, axis)
9、數學運算
以三角函數為例:
a = np.array([0,30,45,60,90])
print ('不同角度的正弦值:')
# 通過乘 pi/180 轉化為弧度
print (np.sin(a*np.pi/180))
print ('\n')
print ('數組中角度的余弦值:')
print (np.cos(a*np.pi/180))
print ('\n')
print ('數組中角度的正切值:')
print (np.tan(a*np.pi/180))
不同角度的正弦值:
[0. 0.5 0.70710678 0.8660254 1. ]
數組中角度的余弦值:
[1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
6.12323400e-17]
數組中角度的正切值:
[0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
1.63312394e+16]
其他的數學運算
四舍五入: numpy.around()
向下取整:numpy.floor()
向上取整:numpy.ceil()
指數運算:numpy.power()
余數:numpy.mod()
加減乘除: add(),subtract(),multiply() 和 divide()
倒數:numpy.reciprocal()
100、tile 平鋪
參考:https://blog.csdn.net/weixin_41998772/article/details/113563806
用法tile(A, reps)
tile是平鋪的意思。即將數組A是為瓷磚,在一個二維平面reps平鋪開來
0、給定一個數組
from numpy import *
c = array([[1,2],[3,4]])
print(c)
Output:
[[1 2]
[3 4]]
1、橫向平鋪
print(tile(c,4))
#等效為print(tile(c,(1,4)))
Output:
[[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]]

2、縱向平鋪
print(tile(c,(3,1)))
Output:
[[1 2]
[3 4]
[1 2]
[3 4]
[1 2]
[3 4]]

3、橫向縱向平鋪
print(tile(c,(3,4)))
Output:
[[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]
[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]
[1 2 1 2 1 2 1 2]
[3 4 3 4 3 4 3 4]]

101、sum max min 最值 等統計函數
計算某一維的sum值,同時該維消失。
0、給定一個數組
import numpy as np
b = np.arange(24).reshape(2,3, 4) # 一個2*3*4的三維數據
print(b)
output >>
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
1、計算某一維的sum
print(b.sum(axis=0)) #0維(0~2)
output >>
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
print(b.sum(axis=1)) #1維(0~2)
output >>
[[12 15 18 21]
[48 51 54 57]]
2、計算某一維的max
print(b.max(axis=1)) #1維(0~2
[[ 8 9 10 11]
[20 21 22 23]]
min max跟numpy.amin amax函數是一樣的,只是調用方式不同。
初次之外,還有一下統計函數:
numpy.ptp() 計算數組中元素最大numpy.percentile()值與最小值的差(最大值 - 最小值)。
numpy.percentile()表示小于這個值的觀察值的百分比
numpy.median() 函數用于計算數組 a 中元素的中位數(中值)
numpy.mean() 函數返回數組中元素的算術平均值,如果提供了軸,則沿其計算。
numpy.average() 函數根據在另一個數組中給出的各自的權重計算數組中元素的加權平均值。
np.std 標準差
np.var方差
102、argsort 索引 排序等
(一)argsort函數返回的是數組值從小到大的索引值
1、一維數組
import numpy as np
x = np.array([8,7,9,4,5,3,10,1,20])
print(np.argsort(x)) #or use x.argsort()
output>>
[7 5 3 4 1 0 2 6 8]
2、多維數組
import numpy as np
b = np.arange(24).reshape(2,3, 4) # 一個2*3*4的三維數據
b = np.array([[[ 8, 5, 7, 5],
[45, 2,67, 5],
[ 4,12,98,45]],
[[ 4,89,90,87],
[ 4, 6, 8,11],
[ 5, 6, 1, 6]]])
print(np.argsort(b,axis=1)) #or use print(b.argsort(axis=1)) 從小到大
output >>
[[[2 1 0 0]
[0 0 1 1]
[1 2 2 2]]
[[0 1 2 2]
[1 2 1 1]
[2 0 0 0]]]
print(np.argsort(-b,axis=1)) #or use print(-b.argsort(axis=1)) 從大到小
output>>
[[[1 2 2 2]
[0 0 1 0]
[2 1 0 1]]
[[2 0 0 0]
[0 1 1 1]
[1 2 2 2]]]
(二)numpy.sort進行排序
a = np.array([[3,7],[9,1]])
>>
[[3 7]
[9 1]]
print (np.sort(a))
>> #默認驗證最后一個軸排序
[[3 7]
[1 9]]
print (np.sort(a, axis = 0))
>>
[[3 1]
[9 7]]
除此之外,還有lexsort()、msort、sort_complex、partition、argpartition等。

浙公網安備 33010602011771號