三、Numpy
- 簡介
- ndarray
- 通用函數
- 其他
1、簡介
Numpy是高性能科學計算和數據分析的基礎包。它也是pandas等其他數據分析的工具的基礎,基本所有數據分析的包都用過它。NumPy為Python帶來了真正的多維數組功能,並且提供了豐富的函數庫處理這些數組。它將常用的數學函數都支持向量化運算,使得這些數學函數能夠直接對數組進行操作,將本來需要在Python級別進行的循環,放到C語言的運算中,明顯地提高了程序的運算速度。
安裝方法:
pip install numpy
引用方式:
import numpy as np
這是官方認證的導入方式,可能會有人說為什么不用from numpy import *
,是因為在numpy當中有一些方法與Python中自帶的一些方法,例如max
、min
等沖突,為了避免這些麻煩大家就約定俗成的都使用這種方法。
2、ndarray -多維數組對象
Numpy的核心特征就是N-維數組對——ndarray.
1、為什么要是用ndarray?
接下來我們可以通過具體的實例來展示一下ndarray的優勢。
現在有這樣一個需求:
已知若干家跨國公司的市值(美元),將其換算為人民幣
按照Python當中的方法
第一種:是將所有的美元通過for循環依次迭代出來,然后用每個公司的市值乘以匯率
第二種:通過map方法和lambda函數映射
這些方法相對來說也挺好用的,但是再來看通過ndarray對象是如何計算的
通過ndarray這個多維數組對象可以讓這些批量計算變得更加簡單,當然這只它其中一種優勢,接下來就通過具體的操作來發現。
2、創建ndarray對象
np.array()
3、ndarray是一個多維數組列表
接下來就多維數組舉個例子:
有的人可能會說了,這個數組跟Python中的列表很像啊,它和列表有什么區別呢?
- 數組對象內的元素類型必須相同
- 數組大小不可修改
4、常用屬性
屬性 | 描述 | |
---|---|---|
T | 數組的轉置(對高維數組而言) | |
dtype | 數組元素的數據類型 | |
size | 數組元素的個數 | |
ndim | 數組的維數 | |
shape | 數組的維度大小(以元組形式) |
T:轉置
li1 = [
[1,2,3],
[4,5,6]
]
a = np.array(li1)
a.T
執行結果:
array([[1, 4],
[2, 5],
[3, 6]])
就相當於是將行變成列,列變成行,它也是一個比較常用的方法
5、數據類型
- dtype
類型 | 描述 | |
---|---|---|
布爾型 | bool_ | |
整型 | int_ int8 int16 int32 int 64 | |
無符號整型 | uint8 uint16 uint32 uint64 | |
浮點型 | float_ float16 float32 float64 | |
復數型 | complex_ complex64 complex128 |
整型:
int32只能表示(-2**31,2**31-1),因為它只有32個位,只能表示2**32個數
無符號整型:
只能用來存正數,不能用來存負數
補充:
astype()方法可以修改數組的數據類型
6、ndarray-創建
方法 | 描述 | |
---|---|---|
array() | 將列表轉換為數組,可選擇顯式指定dtype | |
arange() | range的numpy版,支持浮點數 | |
linspace() | 類似arange(),第三個參數為數組長度 | |
zeros() | 根據指定形狀和dtype創建全0數組 | |
ones() | 根據指定形狀和dtype創建全1數組 | |
empty() | 根據指定形狀和dtype創建空數組(隨機值) | |
eye() | 根據指定邊長和dtype創建單位矩陣 |
1、arange():
np.arange(1.2,10,0.4)
執行結果:
array([1.2, 1.6, 2. , 2.4, 2.8, 3.2, 3.6, 4. , 4.4, 4.8, 5.2, 5.6, 6. ,
6.4, 6.8, 7.2, 7.6, 8. , 8.4, 8.8, 9.2, 9.6])
# 在進行數據分析的時候通常我們遇到小數的機會遠遠大於遇到整數的機會,這個方法與Python內置的range的使用方法一樣
-----------------------------------------------------------------
2、linspace()
np.linspace(1,10,20)
執行結果:
array([ 1. , 1.47368421, 1.94736842, 2.42105263, 2.89473684,
3.36842105, 3.84210526, 4.31578947, 4.78947368, 5.26315789,
5.73684211, 6.21052632, 6.68421053, 7.15789474, 7.63157895,
8.10526316, 8.57894737, 9.05263158, 9.52631579, 10. ])
# 這個方法與arange有一些區別,arange是顧頭不顧尾,而這個方法是顧頭又顧尾,在1到10之間生成的二十個數每個數字之間的距離相等的,前后兩個數做減法肯定相等
----------------------------------------------------------------
3、zeros()
np.zeros((3,4))
執行結果:
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
# 會用0生成三行四列的一個多維數組
---------------------------------------------------------------------
4、ones()
np.ones((3,4))
執行結果:
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
# 會用1生成三行四列的一個多維數組
------------------------------------------------------------------------
5、empty()
np.empty(10)
執行結果:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
# 這個方法只申請內存,不給它賦值
-----------------------------------------------------------------------
6、eye()
np.eye(5)
執行結果:
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.]])
7、索引和切片
- 數組和標量(數字)之間運算
li1 = [
[1,2,3],
[4,5,6]
]
a = np.array(li1)
a * 2
運行結果:
array([[ 2, 4, 6],
[ 8, 10, 12]])
- 同樣大小數組之間的運算
# l2數組
l2 = [
[1,2,3],
[4,5,6]
]
a = np.array(l2)
# l3數組
l3 = [
[7,8,9],
[10,11,12]
]
b = np.array(l3)
a + b # 計算
執行結果:
array([[ 8, 10, 12],
[14, 16, 18]])
- 索引
# 將一維數組變成二維數組
arr = np.arange(30).reshape(5,6) # 后面的參數6可以改為-1,相當於占位符,系統可以自動幫忙算幾列
arr
# 將二維變一維
arr.reshape(30)
# 索引使用方法
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, 27, 28, 29]])
現在有這樣一組數據,需求:找到20
列表寫法:arr[3][2]
數組寫法:arr[3,2] # 中間通過逗號隔開就可以了
- 切片
arr數組
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, 27, 28, 29]])
arr[1:4,1:4] # 切片方式
執行結果:
array([[ 7, 8, 9],
[13, 14, 15],
[19, 20, 21]])
切片不會拷貝,直接使用的原視圖,如果硬要拷貝,需要在后面加.copy()方法
最后會發現修改切片后的數據影響的依然是原數據。有的人可能對一點機制有一些不理解的地方,像Python中內置的都有賦值的機制,而Numpy去沒有,其實是因為NumPy的設計目的是處理大數據,所以你可以想象一下,假如NumPy堅持要將數據復制來復制去的話會產生何等的性能和內存問題。
- 布爾型索引
現在有這樣一個需求:給一個數組,選出數組種所有大於5的數。
li = [random.randint(1,10) for _ in range(30)]
a = np.array(li)
a[a>5]
執行結果:
array([10, 7, 7, 9, 7, 9, 10, 9, 6, 8, 7, 6])
----------------------------------------------
原理:
a>5會對a中的每一個元素進行判斷,返回一個布爾數組
a > 5的運行結果:
array([False, True, False, True, True, False, True, False, False,
False, False, False, False, False, False, True, False, True,
False, False, True, True, True, True, True, False, False,
False, False, True])
----------------------------------------------
布爾型索引:將同樣大小的布爾數組傳進索引,會返回一個有True對應位置的元素的數組
3、通用函數
能對數組中所有元素同時進行運算的函數就是通用函數
常見通用函數:
能夠接受一個數組的叫做一元函數,接受兩個數組的叫二元函數,結果返回的也是一個數組
- 一元函數:
函數 | 功能 | |
---|---|---|
abs、fabs | 分別是計算整數和浮點數的絕對值 | |
sqrt | 計算各元素的平方根 | |
square | 計算各元素的平方 | |
exp | 計算各元素的指數e**x | |
log | 計算自然對數 | |
sign | 計算各元素的正負號 | |
ceil | 計算各元素的ceiling值 | |
floor | 計算各元素floor值,即小於等於該值的最大整數 | |
rint | 計算各元素的值四舍五入到最接近的整數,保留dtype | |
modf | 將數組的小數部分和整數部分以兩個獨立數組的形式返回,與Python的divmod方法類似 | |
isnan | 計算各元素的正負號 | |
isinf | 表示那些元素是無窮的布爾型數組 | |
cos,sin,tan | 普通型和雙曲型三角函數 |
- 二元函數:
函數 | 功能 | |
---|---|---|
add | 將數組中對應的元素相加 | |
subtract | 從第一個數組中減去第二個數組中的元素 | |
multiply | 數組元素相乘 | |
divide、floor_divide | 除法或向下圓整除法(舍棄余數) | |
power | 對第一個數組中的元素A,根據第二個數組中的相應元素B計算A**B | |
maximum,fmax | 計算最大值,fmax忽略NAN | |
miximum,fmix | 計算最小值,fmin忽略NAN | |
mod | 元素的求模計算(除法的余數) |
補充內容:浮點數特殊值
浮點數:float
浮點數有兩個特殊值:
1、nan(Not a Number):不等於任何浮點數(nan != nan)
---------------------------------------------
2、inf(infinity):比任何浮點數都大
---------------------------------------------
- Numpy中創建特殊值:np.nan、np.inf
- 數據分析中,nan常被用作表示數據缺失值
3.1、數學統計方法
函數 | 功能 | |
---|---|---|
sum | 求和 | |
cumsum | 求前綴和 | |
mean | 求平均數 | |
std | 求標准差 | |
var | 求方差 | |
min | 求最小值 | |
max | 求最大值 | |
argmin | 求最小值索引 | |
argmax | 求最大值索引 |
3.2、隨機數
隨機數生成函數在np.random的子包當中
常用函數
函數 | 功能 | |
---|---|---|
rand | 給定形狀產生隨機數組(0到1之間的數) | |
randint | 給定形狀產生隨機整數 | |
chocie | 給定形狀產生隨機選擇 | |
shuffle | 與random.shuffle相同 | |
uniform | 給定形狀產生隨機數組 |