主要介紹Python中的Numpy入門教程,著重講解了矩陣中的數組操作。
[TOC]
# Numpy是什么
NumPy是Python中的一個運算速度非常快的一個數學庫,一般與Scipy、matplotlib一起使用,它非常重視數組。它允許你在Python中進行向量和矩陣計算,并且由于許多底層函數實際上是用C編寫的,因此你可以體驗在原生Python中永遠無法體驗到的速度。
> NumPy絕對是科學Python成功的關鍵之一,如果你想要進入Python中的數據科學和/或機器學習,你就要必須學習它。
在以下的代碼示例中,總是先導入了numpy:
```
>>> import numpy as np
>>> print(np.version.version)
1.14.0
```
# 數組基礎
NumPy圍繞這些稱為數組的事物展開,它被稱之為`ndarrays`。使用NumPy提供的這些數組,我們就可以以閃電般的速度執行各種有用的操作,如矢量和矩陣、線性代數等數學運算!,
> 多維數組的類型是:`numpy.ndarray`。
```
>>>data = [1,2,3,4]?
>>>print(type(data))
<class 'list'>
>>>array=np.array(data)
>>>print(type(array))
<class 'numpy.ndarray'>
```
## 使用NumPy表示向量
以list或tuple變量為參數產生一維數組:
```
>>> print(np.array([1,2,3,4]))
[1 2 3 4]
>>> print(np.array((1.2,2,3,4)))
[ 1.2 2. 3. 4. ]
>>> print(type(np.array((1.2,2,3,4))))
<type 'numpy.ndarray'>
```
~~~
# 1D Array
a = np.array([0, 1, 2, 3, 4])
b = np.array((0, 1, 2, 3, 4))
c = np.arange(5)
d = np.linspace(0, 2*np.pi, 5)
print(a) # >>>[0 1 2 3 4]
print(b) # >>>[0 1 2 3 4]
print(c) # >>>[0 1 2 3 4]
print(d) # >>>[ 0. 1.57079633 3.14159265 4.71238898 6.28318531]
print(a[3]) # >>>3
~~~
上面的代碼顯示了創建數組的4種不同方法。最基本的方法是將序列傳遞給NumPy的array()函數; 你可以傳遞任何序列(類數組),而不僅僅是常見的列表(list)數據類型。
## 多維數組
以list或tuple變量為元素產生二維數組
~~~
# MD Array,
a = np.array([[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25],
[26, 27, 28 ,29, 30],
[31, 32, 33, 34, 35]])
print(a[2,4]) # >>>25
~~~
為了創建一個2D(二維)數組,我們傳遞一個列表的列表(或者是一個序列的序列)給array()函數。如果我們想要一個3D(三維)數組,我們就要傳遞一個列表的列表的列表,如果是一個4D(四維)數組,那就是列表的列表的列表的列表,以此類推。
> 請注意2D(二維)數組(在我們的朋友空格鍵的幫助下)是如何按行和列排列的。要索引2D(二維)數組,我們只需引用行數和列數即可。
生成數組的時候,可以指定數據類型,例如numpy.int32, numpy.int16, and numpy.float64等:
```
>>> print(np.array((1.2,2,3,4), dtype=np.int32))
[1 2 3 4]
```
> 浮點數轉換int32類型時采用的是截尾操作。
# 常用函數
## 使用numpy.arange方法
```
>>> print(np.arange(15))
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
>>> print(type(np.arange(15)))
<class 'numpy.ndarray'>
```
```
>>> print(np.arange(15).reshape(3,5))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
>>> print(type(np.arange(15).reshape(3,5)))
<class 'numpy.ndarray'>
```
## 使用numpy.linspace方法
例如,在從1到10中產生10個數:
```
>>> print(np.linspace(1,10,10))
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
```
## 使用numpy.zeros,numpy.ones,numpy.eye等方法可以構造特定的矩陣
```
>>> print(np.zeros((3,4)))
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
>>> print(np.ones((3,4)))
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
>>>print(np.eye(3))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
```
創建一個三維數組:
```
>>>print(np.ones((3,4,5)))
[[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]]
```
## 獲取數組的屬性:
```
>>> a = np.zeros((2,2,2))
>>> print(a.ndim)?? #數組的維數
3
>>> print(a.shape)? #數組每一維的大小
(2, 2, 2)
>>> print(a.size)?? #數組的元素數
8
>>> print(a.dtype)? #元素類型
float64
>>> print(a.itemsize) #每個元素所占的字節數
8
```
## 數組索引,切片,賦值
```
>>> a = np.array( [[2,3,4],[5,6,7]] )
>>> print a
[[2 3 4]
[5 6 7]]
>>> print a[1,2]
7
>>> print a[1,:]
[5 6 7]
>>> print a[1,1:2]
[6]
>>> a[1,:] = [8,9,10]
>>> print a
[[ 2 3 4]
[ 8 9 10]]
```
## 使用for操作元素
```
>>> for x in np.linspace(1,3,3):
... print(x)
...
1.0
2.0
3.0
```
## 基本的數組運算
先構造數組a、b:
```
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print a
[[ 1. 1.]
[ 1. 1.]]
>>> print b
[[ 1. 0.]
[ 0. 1.]]
```
數組的加減乘除:
```
>>> print a > 2
[[False False]
[False False]]
>>> print a+b
[[ 2. 1.]
[ 1. 2.]]
>>> print a-b
[[ 0. 1.]
[ 1. 0.]]
>>> print b*2
[[ 2. 0.]
[ 0. 2.]]
>>> print (a*2)*(b*2)
[[ 4. 0.]
[ 0. 4.]]
>>> print b/(a*2)
[[ 0.5 0. ]
[ 0. 0.5]]
>>> print (a*2)**4
[[ 16. 16.]
[ 16. 16.]]
```
?使用數組對象自帶的方法:
```
>>> a.sum()
4.0
>>> a.sum(axis=0) #計算每一列(二維數組中類似于矩陣的列)的和
array([ 2., 2.])
>>> a.min()
1.0
>>> a.max()
1.0
```
使用numpy下的方法:
```
>>> np.sin(a)
array([[ 0.84147098, 0.84147098],
[ 0.84147098, 0.84147098]])
>>> np.max(a)
1.0
>>> np.floor(a)
array([[ 1., 1.],
[ 1., 1.]])
>>> np.exp(a)
array([[ 2.71828183, 2.71828183],
[ 2.71828183, 2.71828183]])
>>> np.dot(a,a) ##矩陣乘法
array([[ 2., 2.],
[ 2., 2.]])
```
## 合并數組
使用numpy下的vstack和hstack函數:
```
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print np.vstack((a,b))
[[ 1. 1.]
[ 1. 1.]
[ 1. 0.]
[ 0. 1.]]
>>> print np.hstack((a,b))
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
```
看一下這兩個函數有沒有涉及到淺拷貝這種問題:
```
>>> c = np.hstack((a,b))
>>> print(c)
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
>>> a[1,1] = 5
>>> b[1,1] = 5
>>> print(c)
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
```
可以看到,a、b中元素的改變并未影響c。
## 深拷貝數組
數組對象自帶了淺拷貝和深拷貝的方法,但是一般用深拷貝多一些:
復制代碼代碼如下:
```
>>> a = np.ones((2,2))
>>> b = a
>>> b is a
True
>>> c = a.copy() #深拷貝
>>> c is a
False
```
## 基本的矩陣運算
轉置:
```
>>> a = np.array([[1,0],[2,3]])
>>> print(a)
[[1 0]
[2 3]]
>>> print(a.transpose()
)
[[1 2]
[0 3]]
```
跡:
```
>>> print(np.trace(a)
)
4
```
numpy.linalg模塊中有很多關于矩陣運算的方法:
```
>>> import numpy.linalg as nplg
```
特征值、特征向量:
```
>>> print(nplg.eig(a)
)
(array([ 3., 1.]), array([[ 0. , 0.70710678],
[ 1. , -0.70710678]]))
```