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)#
參考和轉載:
http://blog.csdn.net/sunny2038/article/details/8907736