1.Python基礎學習之高級數組(一) 1.1視圖:就是與較大數組共用相同數據的較小數組。Numpy包提供數據視圖的概念是為了精確地控制記憶體的使用方式。 數組視圖、切片視圖、轉置和重塑視圖等 數組視圖實例: from numpy import* M=array([[1.,2.],[3.,4.]]) ...
1.Python基礎學習之高級數組(一)
1.1視圖:就是與較大數組共用相同數據的較小數組。Numpy包提供數據視圖的概念是為了精確地控制記憶體的使用方式。 數組視圖、切片視圖、轉置和重塑視圖等
數組視圖實例:
from numpy import*
M=array([[1.,2.],[3.,4.]])
v=M[0,:] #切片是數組的視圖(切片視圖),它與M享有相同的數據。
print(v)
v[-1]=0
print(v)
print(M) #註意:如果修改v,M也會同時被修改
print(v.base) #數組的屬性base能夠訪問擁有數據的對象,若數組擁有本身的數據,
#則其屬性base的值為none
print(v.base is M)
print(M.base)
運行結果:
[1. 2.]
[1. 0.]
[[1. 0.]
[3. 4.]]
[[1. 0.]
[3. 4.]]
True
None
切片視圖:只有基本切片(主要為帶冒號的索引表達式)將返回視圖,而任何高級切片(如使用布爾值的切片)都將返回數據的副本。
例如:
a=arange(4)
b=a[[2,3]] #索引是一個列表[2,3],b是數組
print(b)
print(b.base is None) #數據被覆制,b是數組
c=a[1:3]
print(c)
print(c.base is None)
M=M[:]
print(M)
補充:Numpy的試圖與副本:
視圖:是數據的一個別稱或引用,通過該別稱或引用亦便訪問、操作原有數據,但是原有數據不會產生拷貝。如果對視圖進行修改,他就會影響到原有數據(原有數據同時被修改),物理記憶體在同一位置。
副本: 是對一個數據的完整拷貝,如果對副本進行修改,它不會影響到原有數據,物理地址不存在同一個位置。
具體分為:
① 無複製:簡單的複製不會創建數組對象的副本。它使用原始數據的相同id()來訪問它。Id()返回python對象的通用標識符,類似於C中的指針。
一個數組的任何變化都反映在另一個數組上。例如,一個數組的形狀改變另一個數組的形狀。
② 視圖或者淺複製:Numpy擁有ndarray.view()方法,是一個新的數組對象,並且可查看原始數組的相同數據。新數組的維數更改不會更改原始數據的維數。
實例:
from numpy import*
a=arange(6).reshape(3,2)
print(a)
b=a.view()
print(b)
c=b.reshape(2,3)
print(c)
print(a.shape) #註意:數組b(新視圖)的維數改變不影響原始數據的維數
print(id(a))
print(id(b)) #兩個數組的id不變
運行結果:
[[0 1]
[2 3]
[4 5]]
[[0 1]
[2 3]
[4 5]]
[[0 1 2]
[3 4 5]]
(3, 2)
144810752
144810112
③ 深複製(副本):ndarray.copy()函數創建一個深層副本。是數組及其數據的完整副本,不與原始數據共用。
實例:import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print ('數組 a:')
print (a)
print ('創建 a 的深層副本:' )
b = a.copy()
print ('數組 b:' )
print (b)
# b 與 a 不共用任何內容
print ('我們能夠寫入 b 來寫入 a 嗎?' )
print (b is a )
print ('修改 b 的內容:')
b[0,0] = 100
print ('修改後的數組 b:')
print (b)
print ('a 保持不變:')
print (a)
運算結果:
數組 a:
[[10 10]
[ 2 3]
[ 4 5]]
創建 a 的深層副本:
數組 b:
[[10 10]
[ 2 3]
[ 4 5]]
我們能夠寫入 b 來寫入 a 嗎?
False
修改 b 的內容:
修改後的數組 b:
[[100 10]
[ 2 3]
[ 4 5]]
a 保持不變:
[[10 10]
[ 2 3]
[ 4 5]]
- 2.數組比較:
數組比較是為了檢查兩個矩陣是否彼此接近。
布爾數組:元素是bool類型的數組。任何作用於數組的比較運算都將創建一個布爾數組,而不是布爾值。
例如:M=array([[2.,3.],[1.,4.]])
print(M>2) #數組的比較運算創建了布爾數組
運行結果為:[[False True]
[False True]]
註意:在條件語句中不能直接使用數組比較,應使用all和any方法。
例:
M=array([[2.,3.],[1.,4.]])
N=array([[1.,2.],[3.,3.]])
print(M==N) #返回布爾數組
print((M==N).all())
print((M!=N).any()) #返回Ture
if (abs(N-M)<1e-10).all(): #abs()函數返回數字的絕對值
print("The two arrays are close enough")
運行結果:[[False False]
[False False]]
False
True
相等判斷:兩個浮點數組的相等判斷不是直接進行。在Numpy中用allclose()函數來判斷,該函數判斷了兩個到達精度的數組是否相等。
因為兩個浮點數可能無限接近而不相等。
例如:
data=random.rand(2)*1e-3 #random.rand()生成隨機數組
small_error=random.rand(2)*1e-16
print(data)
print(small_error)
print(data==data+small_error)
print(allclose(data,data+small_error,rtol=1.e-5,atol=1.e-8)) #其誤差是根據相對誤差界限#rtol和atol給出的
運行結果:
[2.46971243e-04 6.77622235e-05]
[2.78354596e-17 6.88850359e-17]
[False False] True
- 3 數組索引
(1)除去基本的切片技術(見https://www.cnblogs.com/chenzhijuan-324/p/10577513.html)可以通過組合切片和整數來索引數組。這裡介紹使用布爾數組根據數組中的元素的值來訪問和修改數組的一部分。註意:索引操作的結果總是一個向量。
例如:
B=array([[True,False],[False,True]])
M=array([[2,3],[1,4]])
print(M[B]) #根據布爾數組進行索引
M[B]=10,20 #用其他值來替代索引所得的值
print(M)
M[M>2]=0 #M的所有大於2的元素均被0替代
print(M)
運算結果:
[2 4]
[[10 3]
[ 1 20]]
[[0 0]
[1 0]]
(2) Where命令:
基本結構:Where(condition,a,b) 該結構將布爾數組作為條件,並返回滿足條件的數組元組的索引,或者根據布爾數組中的值返回不同的值
例如:
x=linspace(-4,4,5)
print(x)
print(where(x>0,sqrt(x),0))
print(where(x>0,1,-1)) #表示若x>0,返回1,否則返回-1
a=arange(9)
b=a.reshape((3,3))
print(b)
print(where(a>5)) #返回一個元組,這個元組包含了滿足條件的元素的索引。
print(where(b>5))
運行結果:
[-4. -2. 0. 2. 4.]
[0. 0. 0. 1.41421356 2. ]
[-1 -1 -1 1 1]
[[0 1 2]
[3 4 5]
[6 7 8]]
(array([6, 7, 8], dtype=int64),)
(array([2, 2, 2], dtype=int64), array([0, 1, 2], dtype=int64))