Numpy 陣列基礎操作--索引、組合、分割、複製、遍歷、轉換、序列化(四)
阿新 • • 發佈:2019-01-26
Numpy 陣列基礎操作
1.陣列索引訪問
#!/usr/bin/env python # encoding: utf-8 import numpy as np b = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=int) c = b[0,1] #1行 第二個單元元素 # 輸出: 2 d = b[:,1] #所有行 第二個單元元素 # 輸出: [ 2 5 8 11] e = b[1,:] #2行 所有單元元素 # 輸出: [4 5 6] f = b[1,1:] #2行 第2個單元開始以後所有元素 # 輸出: [5 6] g = b[1,:2] #2行 第1個單元開始到索引為2以前的所有元素 # 輸出: [4 5]
2.陣列的組合(函式)
'''
# 組合函式
#建立兩個測試陣列
# arange 建立一個含有9個元素的一維
# reshape方法,可以建立一個改變了尺寸的新陣列,原陣列的shape保持不變:
# 在這裡 reshape(3,3) 將生成一個 3個元素為一組的 3維陣列
'''
#建立兩個測試陣列 a = np.arange(9).reshape(3,3) ''' array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) ''' b = 2 * a ''' array([[ 0, 2, 4], [ 6, 8, 10], [12, 14, 16]]) '''
#水平組合
np.hstack((a, b)) ''' array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]]) ''' #通過concatenate函式並指定相應的軸 (axis=1 水平,axis=0 垂直) con = np.concatenate((a, b), axis=1) ''' array([[ 0, 1, 2, 0, 2, 4], [ 3, 4, 5, 6, 8, 10], [ 6, 7, 8, 12, 14, 16]]) '''
#垂直組合
np.vstack((a, b))
'''
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
'''
#或者使用concatenate
con = np.concatenate((a, b), axis=0)
#深度組合 dstack(就是在陣列的第三個軸(即深度)上組合,生成一個新的列表陣列)
np.dstack((a, b))
'''
array([[[ 0, 0],
[ 1, 2],
[ 2, 4]],
[[ 3, 6],
[ 4, 8],
[ 5, 10]],
[[ 6, 12],
[ 7, 14],
[ 8, 16]]])
'''
#行組合,行組合可將多個一維陣列作為新陣列的每一行進行組合
#對於2維陣列,其作用就像垂直組合一樣。
one = np.arange(2)
'''
array([0, 1])
'''
two = one + 2
'''
array([2, 3])
'''
np.row_stack((one, two))
'''
array([[0, 1],
[2, 3]])
'''
#列組合(對於2維陣列,其作用就像水平組合一樣。)
np.column_stack((oned, twiceoned))
'''
array([[0, 2],
[1, 3]])
'''
3.陣列分割
在NumPy中,分割陣列的函式有hsplit、vsplit、dsplit和split。可將陣列分割成相同大小的子陣列,或指定原陣列分割的位置。
#水平分割
a = arange(9).reshape(3,3)
'''
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
'''
np.hsplit(a, 3)
'''
[array([[0],
[3],
[6]]),
array([[1],
[4],
[7]]),
array([[2],
[5],
[8]])]
'''
#方法二:用split函式並指定軸為1
np.split(a, 3, axis=1)
#垂直分割
#垂直分割是沿著垂直的軸切分陣列:
np.vsplit(a, 3)
'''
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
'''
#方法二
#solit函式並指定軸為1
np.split(a, 3, axis=0)
#面向深度的分割
#dsplit函式使用的是面向深度的分割
c = arange(27).reshape(3, 3, 3)
'''
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],
[24, 25, 26]]])
'''
np.dsplit(c, 3)
'''
[array([[[ 0],
[ 3],
[ 6]],
[[ 9],
[12],
[15]],
[[18],
[21],
[24]]]),
array([[[ 1],
[ 4],
[ 7]],
[[10],
[13],
[16]],
[[19],
[22],
[25]]]),
array([[[ 2],
[ 5],
[ 8]],
[[11],
[14],
[17]],
[[20],
[23],
[26]]])]
'''
4.判斷陣列是否共享記憶體,也是用來直接判斷資料是複製的還是映象的
#方法一:
a = np.arange(50)
b = a.reshape((5, 10))
print (b.base is a)
#方法二:
print (np.may_share_memory(a, b))
#方法三:
print (b.flags['OWNDATA']) #False -- apparently this is a view
e = np.ravel(b[:, 2])
print (e.flags['OWNDATA']) #True -- Apparently this is a new numpy object.
5.陣列複製和映象( view )
1.)完全不復制 ,簡單的賦值,而不復制陣列物件或它們的資料。
a = np.arange(12)
b = a #不建立新物件
b is a # a和b是同一個陣列物件的兩個名字
# true
b.shape = 3,4 #也改變了a的形狀
print a.shape
'''
(3, 4)
'''
2.) view的用法 檢視方法創造一個新的陣列物件指向同一資料。
事實上,沒有任何資料型別是固定的,主要取決於如何看待這片資料的記憶體區域。
在numpy.ndarray.view中,提供對記憶體區域不同的切割方式,來完成資料型別的轉換,而無須要對資料進行額外的copy,來節約記憶體空間。
c = a.view()
c is a
# false
c.base is a #c是a持有資料的映象
#true
c.shape = 2,6 # a的形狀沒變
print(a.shape) # (3, 4)
c[0,4] = 1234 #a的資料改變了
print a
'''
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
'''
3.)切片陣列返回它的一個檢視
s = a[ : , 1:3] # 獲得每一行1,2處的元素
s[:] = 10 # s[:] 是s的映象。注意區別s=10 and s[:]=10
print a
'''
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
[ 8, 10, 10, 11]])
'''
4.)深複製,這個複製方法完全複製陣列和它的資料。
d = a.copy() #建立了一個含有新資料的新陣列物件
d is a
#False
d.base is a #d和a現在沒有任何關係
#False
d[0,0] = 9999
print a
'''
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
[ 8, 10, 10, 11]])
'''
5.)在影象處理中的應用
當需要對輸入影象三個通道進行相同的處理時,使用cv2.split和cv2.merge是相當浪費資源的,因為任何一個通道的資料對處理來說都是一樣的,我們可以用view來將其轉換為一維矩陣後再做處理,這要不需要額外的記憶體開銷和時間開銷。
def createFlatView(array):
"""Return a 1D view of an array of any dimensionality."""
flatView = array.view()
flatView.shape = array.size
return flatView
5.陣列遍歷
a = np.arange(9).reshape(3,3)
for row in a:
print row
'''
[0 1 2]
[3 4 5]
[6 7 8]
'''
#對陣列中每個元素都進行處理,可以使用flat屬性,該屬性是一個數組元素迭代器:
for element in a.flat:
print element
'''
0 1 2 3 4 5 6 7 8
'''
6.資料型別轉換
np.float64(42) # to float64
#42.0
np.int8(42.0) # to int8
#42
np.bool(42) # to bool
#True
np.bool(42.0) # to bool
#True
np.float(True) # to float
#1.0
#函式的引數中可以指定引數的型別
arange(7, dtype=uint16)
array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)
6.陣列序列化和反序列化
序列化是將物件狀態轉換為可保持或傳輸的形式的過程。序列化的補集是反序列化,後者將流轉換為物件。這兩個過程一起保證資料易於儲存和傳輸。
python 提供pickle, cPickle 物件序列化/反序列化
這裡使用numpy 提供的函式
#預定義資料欄位名稱和型別
table = np.loadtxt('example.txt',dtype='names': ('ID', 'Result', 'Type'),\
'formats': ('S4', 'f4', 'i2'))
np.savetxt('somenewfile.txt')#序列化
#二進位制檔案載入,儲存
data = np.empty((1000, 1000))
np.save('test.npy', data)
np.savez('test.npz', data)#採用壓縮
newdata = np.load('test.npy')
7.陣列中最大值最小值
mat.max(0)#n維陣列axis=0維度的最小值,最大值
mat.min(0)#
參考和轉載: