一、NumPy數組對象
NumPy中的ndarray是一個多維數組對象,該對象由兩部分組成:
- 實際的數據
- 描述這些數據的元數據
NumPy中可以用arange函數快速創建一維數組:
In: import numpy as np
In: a = np.arange(5)
In: a
Out: array([0, 1, 2, 3, 4])
In: a.dtype
Out: dtype('int32') #表示有符號的32位整型
In: f = a.astype(np.float64) #astype可以顯式轉換其dtype(會創建出一個新數組),若失敗引發TypeError
In: f.dtype
Out: dtype('float64')
In: a.shape #返回維度
Out: (5,) #返回一個元祖(tuple)此處只有一維,所以元祖中只有一個元素
數組基本說明:
方法 | 說明 |
---|---|
shape | 返回數組各維度大小 |
dtype | 返回數組數據類型 |
astype | 轉換數組的數據類型 |
數據類型
類型 | 類型代碼 | 說明 |
---|---|---|
int8、uint8 | i1、u1 | 有符號和無符號的8位(1個字節)整型 |
int16、uint16 | i2、u2 | 有符號和無符號的16位(2個字節)整型 |
int32、uint32 | i4、u4 | 有符號和無符號的32位(4個字節)整型 |
int64、uint64 | i8、u8 | 有符號和無符號的64位(8個字節)整型 |
float16 | f2 | 半精度浮點數 |
float32 | f4或f | 標準的單精度浮點數,與C的float兼容 |
float64 | f8或d | 標準的雙精度浮點數,與C的double和python的float對象兼容 |
float128 | f16或g | 擴展精度浮點數 |
complex64、complex128、complex256 | c8、c16、c32 | 分別用兩個32位、64位或128位浮點數標書的複數 |
bool | ? | 布爾類型 |
object | O | python對象類型 |
string | S | 固定長度的字符串類型,每個字符一個字節 |
unicode | U | 固定長度的unicode類型,字節數由平臺決定 |
二、數組的創建
數組的創建主要使用array函數,它接受一切序列型的對象(包括其他數組),嵌套序列會被轉換爲一個多維數組,比如由一組等長列表組成的列表:
In:data1 = [[1,3,5,7],[6,3,2,9]]
In:arr1 = np.array(data1)
In:arr1
Out:array([[1, 3, 5, 7],
[6, 3, 2, 9]])
In:arr1.shape
Out:(2, 4)
In:m = np.array([np.arange(2),np.arange(2)])
In:m
Out:array([[0, 1],
[0, 1]])
In:m.shape
Out:(2,2)
此外,還有其他一系列新建數組的函數,如zeros和ones分別可以創建指定長度或形狀的全0或全1數組,empty可以創建一個沒有任何具體值的數組:
In:np.zeros(10)
Out:array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In:np.zeros((3,6))
Out:
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
In:np.empty((2,3,2))
In:np.ones((2,3,4))
Out:
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
Out:
array([[[1.50668433e-312, 0.00000000e+000],
[8.76794447e+252, 2.15895723e+227],
[6.48224638e+170, 3.67145870e+228]],
[[1.08578811e-095, 9.03292329e+271],
[9.08366793e+223, 1.41075687e+232],
[1.16070543e-028, 2.29179605e-312]]])
In [42]:arr = np.eye(5,5)
In:arr
Out:
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
注:不能想當然認爲empty將返回全0數組,很多情況下,它返回的是一些未初始化的垃圾值。
如下列出主要數組創建函數,無特殊指定,數據類型基本是float:
函數 | 說明 |
---|---|
array | 將輸入數據(列表、元祖、數組或其他序列類型)轉換爲ndarray 。默認直接複製輸入數據 |
asarray | 將輸入轉換爲ndarray,若輸入本身就是一個ndarray就不進行復制 |
arange | 類似於內置的range |
eye | 生成一個對角矩陣 |
random.randn(m,n) | 生成m*n維隨機數組 |
ones、ones_like | ones根據指定形狀創建一個全1數組。ones_like以另一數組爲參數,根據其形狀和dtype創建一個全1數組 |
zeros、zeros_like | 同上,不過產生的是全0數組 |
empty、empty_like | 創建新數組,只分配內存空間但不填充值 |
三、索引與切片
Numpy數組的索引類似於列表:
In [2]:arr = np.arange(10)
In [3]:arr
Out[3]:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [4]:arr[5]
Out[4]:5
In [5]:arr[5:8]
Out[5]:array([5, 6, 7])
In [6]:arr[5:8] = 12
In [7]:arr
Out[7]:array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
跟列表最重要的區別在於,數組切片是原始數組的視圖,這意味着數據不會被複制,視圖上所有修改都會直接反映到源數組上:
In [8]:arr_slice = arr[5:8]
In [9]:arr_slice[1] = 12345
In [10]:arr
Out[10]:array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
In [11]:arr_slice
Out[11]:array([ 12, 12345, 12])
In [12]:arr_slice[:] = 64
In [13]:arr
Out[13]:array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
若要得到切片的副本,就需要顯式地進行復制操作,如arr[5:8].copy
對於二維數組,如:
In:arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
In:arr2[2]
Out:array([7, 8, 9])
In: arr2[0][2]
Out:3
In: arr2[0,2]
Out:3
在多維數組中:
In:arr3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
In:arr3
Out:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
In:arr3[0]
Out:
array([[1, 2, 3],
[4, 5, 6]])
In:old_values = arr3[0].copy()
In:arr3[0] = 42 #標量和數組都可以賦值給arr3[0]
In:arr3
Out:
array([[[42, 42, 42],
[42, 42, 42]],
[[ 7, 8, 9],
[10, 11, 12]]])
In:arr3[0] = old_values
In:arr3
Out:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
切片是沿着一個軸向選取元素的,可以一次傳入多個切片,就像傳入多個索引,“只有冒號”時表示選取整個軸,通過將整數索引和切片混合,可以得到低維度的切片:
In [10]:arr4 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]])
In [11]:arr4
Out[11]:
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18]]])
In [12]:arr4[1, : 2]
Out[12]:
array([[ 7, 8, 9],
[10, 11, 12]])
In [13]:arr4[1, : : 2] #在切片中間隔取值
Out[13]:array([[7, 8, 9]])