一、什麼是Numpy
numpy官方文檔:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750html
NumPy是一個功能強大的Python庫,主要用於對多維數組執行計算。NumPy這個詞來源於兩個單詞-- Numerical和Python。 它是 Python 生態系統中數據分析、機器學習和科學計算的主力軍。它極大地簡化了向量和矩陣的操做處理。Python 數據科學相關的一些主要軟件包(如 scikit-learn、SciPy、pandas 和 tensorflow)都以 NumPy 做爲其架構的基礎部分。除了能對數值數據進行切片(slice)和切塊(dice)以外,使用 NumPy 還能爲處理和調試上述庫中的高級實例帶來極大便利組。它將經常使用的數學函數都支持向量化運算,使得這些數學函數可以直接對數組進行操做,將原本須要在Python級別進行的循環,放到C語言的運算中,明顯地提升了程序的運算速度。python
二、爲何要用Numpy
NumPy是Python中的一個運算速度很是快的一個數學庫,它很是重視數組。它容許你在Python中進行向量和矩陣計算,而且因爲許多底層函數其實是用C編寫的,所以你能夠體驗在原生Python中永遠沒法體驗到的速度。api
import numpy as np import time # 用python自帶方法處理 def func(values): result = [] for v in values: result.append(v * v) return result data = range(10000) %timeit func(data) 運行結果: 1.07 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 用numpy中的方法處理 arr = np.arange(0,10000) %timeit arr ** arr 運行結果: 397 µs ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
NumPy絕對是科學Python成功的關鍵之一,若是你想要進入Python中的數據科學或機器學習,你就要必須學習它。從最後的執行結果來看numpy的處理速度要比python的處理速度快上十幾倍,固然這只是它的其中一項優點,下面就經過一些具體的操做來看一看numpy的用法與優點。數組
三、怎麼用Numpy
安裝方法:數據結構
pip install numpy架構
引用方式:app
import numpy as npdom
這是官方認證的導入方式,可能會有人說爲何不用from numpy import *
,是由於在numpy當中有一些方法與Python中自帶的一些方法,例如max
、min
等衝突,爲了不這些麻煩你們就約定俗成的都使用這種方法。機器學習
Numpy的核心特徵就是N-維數組對——ndarray.ide
3.一、爲何要用ndarray?
numpy全部的操做都是圍繞着數組展開的,這個數組的名字就叫作ndarray
,在學習ndarray數組以前確定有人會說這個東西和Python中的列表差很少啊,爲何不用列表呢,列表還要方便些。其實列表list自己是爲了處理更普遍、更通用的目的而構建的,其實從這一方面來看ndarray對於處理這個數組類型結構的數據會更加方便。
接下來咱們能夠經過具體的實例來展現一下ndarray的優點。 如今有這樣一個需求:
已知若干家跨國公司的市值(美圓),將其換算爲人民幣
按照Python當中的方法 第一種:是將全部的美圓經過for循環依次迭代出來,而後用每一個公司的市值乘以匯率 第二種:經過map方法和lambda函數映射
這些方法相對來講也挺好用的,可是再來看經過ndarray對象是如何計算的
經過ndarray這個多維數組對象可讓這些批量計算變得更加簡單,固然這隻它其中一種優點,接下來就經過具體的操做來發現。
3.二、ndarray-建立
方法 | 描述 |
---|---|
array() | 將列表轉換爲數組,可選擇顯式指定dtype |
arange() | range的numpy版,支持浮點數 |
linspace() | 相似arange(),第三個參數爲數組長度 |
zeros() | 根據指定形狀和dtype建立全0數組 |
ones() | 根據指定形狀和dtype建立全1數組 |
empty() | 根據指定形狀和dtype建立空數組(隨機值) |
eye() | 根據指定邊長和dtype建立單位矩陣 |
一、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的使用方法同樣 ----------------------------------------------------------------- 二、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之間生成的二十個數每一個數字之間的距離相等的,先後兩個數作減法確定相等 ---------------------------------------------------------------- 三、zeros() np.zeros((3,4)) 執行結果: array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]) # 會用0生成三行四列的一個多維數組 --------------------------------------------------------------------- 四、ones() np.ones((3,4)) 執行結果: array([[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]) # 會用1生成三行四列的一個多維數組 ------------------------------------------------------------------------ 五、empty() np.empty(10) 執行結果: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) # 這個方法只申請內存,不給它賦值 ----------------------------------------------------------------------- 六、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.]]) # 對角矩陣
3.三、ndarray是一個多維數組列表
接下來就多維數組舉個例子:
爲了建立一個2維數組,咱們是傳遞了一個列表的列表給這個array()函數。若是咱們想要的是一個三維數組,咱們就必需要一個列表的列表的列表(也就是三層列表),以此類推。
不少狀況下,處理一個新的維度只須要在numpy函數的參數中添加一個逗號
有的人可能會說了,這個數組跟Python中的列表很像啊,它和列表有什麼區別呢?
''' 在python中列表是能夠存任意類型的值的,可是在數組當中的元素必須類型必須相同。這是由於列表中存的只是每一個元素的地址,無論運行多少次,值的位置是不會改變的,不須要在乎數據的類型;而在ndarray當中存的是具體的值,每一次執行都是從新存放。 ''' l1 = ['1','2',4] na = np.array(l1) print(f"ndarry:{id(na[0])}") print(f"list:{id(l1[0])}") > ndarry:2140960887632 list:2140897577592 """ 經過屢次執行其實就能夠發現,ndarray數組的id值一直在不停的換,而list的id值始終保持不變 """
- 數組對象內的元素類型必須相同
- 數組大小不可修改
3.四、經常使用屬性
屬性 | 描述 |
---|---|
T | 數組的轉置(對高維數組而言) |
dtype | 數組元素的數據類型 |
size | 數組元素的個數 |
ndim | 數組的維數 |
shape | 數組的維度大小(以元組形式) |
itemsize | 每一個項佔用的字節數 |
nbytes | 數組中的全部數據消耗掉的字節數 |
# T:轉置 轉置是一種特殊的數據重組形式,能夠返回底層數據的視圖而不須要複製任何內容。 # 通俗點說,轉置就是將數據旋轉90度,行變成列,列變成行。 li1 = [ [1,2,3], [4,5,6] ] a = np.array(li1) a.T 執行結果: array([[1, 4], [2, 5], [3, 6]])
# dtype:返回當前數據的數據類型 arr = np.arange(10) arr.dtype 執行結果: dtype('int32') # size:返回當前數組內存在的元素個數 l1 = [[[1,2,3], [4,5,6]], [[7,8,9], [1,5,9] ]] arr1 = np.array(l1) arr1.size 執行結果: 12 # ndim:返回當前數組維度 l1 = [[[1,2,3], [4,5,6]], [[7,8,9], [1,5,9] ]] arr1 = np.array(l1) arr1.ndim 執行結果: 3 # shape:返回數組維度大小 l1 = [[[1,2,3,4], [4,5,6,5], [6,8,3,6]], [[7,8,9,7], [1,5,9,7], [4,6,8,4] ]] arr1 = np.array(l1) arr1.shape 執行結果: (2, 3, 4) """ 最終三個參數表明的含義依次爲:二維維度,三維維度,每一個數組內數據大小 要注意這些數組必需要是相同大小才能夠 """
3.五、數據類型
- dtype
類型 | 描述 |
---|---|
布爾型 | bool_ |
整型 | int_ int8 int16 int32 int 64 |
無符號整型 | uint8 uint16 uint32 uint64 |
浮點型 | float_ float16 float32 float64 |
整型: int32只能表示(-2**31,2**31-1),由於它只有32個位,只能表示2**32個數 無符號整型: 只能用來存正數,不能用來存負數 """ 補充: astype()方法能夠修改數組的數據類型 示例: data.astype(np.float) """
3.六、向量化數學運算
- 數組和標量(數字)之間運算
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]])
數組與數組之間的向量化運算,兩個運算的數組必須相同大小,不然會報錯
3.七、索引和切片
- 索引
一維索引使用與python自己的列表沒有任何區別,因此接下來主要針對大的是多維數組
# np重塑 arr = np.arange(30).reshape(5,6) # 後面的參數6能夠改成-1,至關於佔位符,系統能夠自動幫忙算幾列
# 將二維變一維 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[0,1:4] # >>array([1, 2, 3]) arr[1:4,0] # >>array([ 6, 12, 18]) arr[::2,::2] # >>array([[ 0, 2, 4], # [12, 14, 16], # [24, 26, 28]]) arr[:,1] # >>array([ 1, 7, 13, 19, 25])
切片不會拷貝,直接使用的原視圖,若是硬要拷貝,須要在後面加.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對應位置的元素的數組
布爾型索引是numpy當中的一個很是經常使用的用法,經過布爾型索引取值方便又快捷。
四、通用函數
能對數組中全部元素同時進行運算的函數就是通用函數
4.一、常見通用函數
可以接受一個數組的叫作一元函數,接受兩個數組的叫二元函數,結果返回的也是一個數組
- 一元函數:
函數 | 功能 |
---|---|
abs、fabs | 分別是計算整數和浮點數的絕對值 |
sqrt | 計算各元素的平方根 |
square | 計算各元素的平方 |
exp | 計算各元素的指數e**x |
log | 計算天然對數 |
sign | 計算各元素的正負號 |
ceil | 計算各元素的ceiling值 |
floor | 計算各元素floor值,即小於等於該值的最大整數 |
rint | 計算各元素的值四捨五入到最接近的整數,保留dtype |
modf | 將數組的小數部分和整數部分以兩個獨立數組的形式返回,與Python的divmod方法相似 |
isnan | 判斷數組中的缺失值 |
isinf | 表示那些元素是無窮的布爾型數組 |
cos,sin,tan | 普通型和雙曲型三角函數 |
如下簡單演示經常使用的幾個一元函數:
# 計算整數絕對值 arr = np.random.randint(-10,10,20) np.abs(arr) > array([9, 7, 3, 1, 5, 8, 7, 9, 4, 2, 7, 3, 4, 6, 6, 9, 2, 5, 8, 1]) ------------------------------------------------------------------------------- # 計算浮點數絕對值 arr = np.random.randn(2,5) np.fabs(arr) > array([[0.09892302, 0.06200835, 1.0324653 , 1.58089607, 0.44506652], [0.34897694, 1.04843539, 0.83976969, 0.4731551 , 0.92229931]]) ------------------------------------------------------------------------------ # 計算各元素的平方根 arr = np.arange(10) np.sqrt(arr) > array([0. , 1. , 1.41421356, 1.73205081, 2. , 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
- 二元函數:
函數 | 功能 |
---|---|
add | 將數組中對應的元素相加 |
subtract | 從第一個數組中減去第二個數組中的元素 |
multiply | 數組元素相乘 |
divide、floor_divide | 除法或向下圓整除法(捨棄餘數) |
power | 對第一個數組中的元素A,根據第二個數組中的相應元素B計算A**B |
maximum,fmax | 計算最大值,fmax忽略NAN |
miximum,fmix | 計算最小值,fmin忽略NAN |
mod | 元素的求模計算(除法的餘數) |
arr = np.random.randint(0,10,5) arr1 = np.random.randint(0,10,5) arr,arr1 > (array([0, 1, 8, 2, 6]), array([5, 4, 1, 7, 0])) ------------------------------------------------------------------------- # add 將數組中對應的元素相加 np.add(arr,arr1) > array([5, 5, 9, 9, 6]) ------------------------------------------------------------------------- # subtract 從第一個數組中減去第二個數組中的元素 np.subtract(arr,arr1) > array([-5, -3, 7, -5, 6]) ------------------------------------------------------------------------- # multiply 數組元素相乘 np.multiply(arr,arr1) > array([ 0, 4, 8, 14, 0]) ------------------------------------------------------------------------- ...
補充內容:浮點數特殊值
浮點數:float 浮點數有兩個特殊值:
一、nan(Not a Number):不等於任何浮點數(nan != nan) --------------------------------------------- 二、inf(infinity):比任何浮點數都大 ---------------------------------------------
- Numpy中建立特殊值:np.nan、np.inf
- 數據分析中,nan常被用做表示數據缺失值
以上函數使用很是方便,使用這些方法可讓數據分析的操做更加便捷。
4.二、數學統計方法
函數 | 功能 |
---|---|
sum | 求和 |
cumsum | 求前綴和 |
mean | 求平均數 |
std | 求標準差 |
var | 求方差 |
min | 求最小值 |
max | 求最大值 |
argmin | 求最小值索引 |
argmax | 求最大值索引 |
arr = np.random.randint(0,10,10) arr > array([2, 9, 6, 5, 4, 2, 9, 8, 0, 5]) ------------------------------------------------------------------------- # sum 求和 np.sum(arr) > 50 ------------------------------------------------------------------------- # cumsum 求前綴和 np.cumsum(arr) array([ 2, 11, 17, 22, 26, 28, 37, 45, 45, 50], dtype=int32) # 依次累加 ------------------------------------------------------------------------- # mean 求平均數 np.mean(arr) > 5.0 ------------------------------------------------------------------------- # 因爲此檔內容太過簡單,後續就不一一展現了 ...
4.三、隨機數
咱們有學過python中生成隨機數的模塊random,在numpy中也有一個隨機數生成函數,它在**np.random
**的子包當中。在Python自帶的random當中只能生成一些簡單、基礎的隨機數,而在np.random當中是能夠生成一些高級的隨機數的。np.random要比Python自帶的random包更加靈活。
函數 | 功能 |
---|---|
rand | 返回給定維度的隨機數組(0到1之間的數) |
randn | 返回給定維度的隨機數組 |
randint | 返回給定區間的隨機整數 |
choice | 給定的一維數組中隨機選擇 |
shuffle | 原列表上將元素打亂(與random.shuffle相同) |
uniform | 給定形狀產生隨機數組 |
seed | 設定隨機種子(使相同參數生成的隨機數相同) |
standard_normal | 生成正態分佈的隨機樣本數 |
# rand 返回給定維度的隨機數組 np.random.rand(2,2,2) > array([[[0.37992696, 0.18115096], [0.78854551, 0.05684808]], [[0.69699724, 0.7786954 ], [0.77740756, 0.25942256]]]) ------------------------------------------------------------------------- # randn 返回給定維度的隨機數組 np.random.randn(2,4) > array([[ 0.76676877, 0.21752554, 2.08444169, 1.51347609], [-2.10082473, 1.00607292, -1.03711487, -1.80526763]]) ------------------------------------------------------------------------- # randint 返回給定區間的隨機整數 np.random.randint(0,20) > 15 ------------------------------------------------------------------------- # chocie 給定的一維數組中隨機選擇 np.random.choice(9,3) # # 從np.range(9)中,(默認)有放回地等機率選擇三個數 > array([5, 8, 2]) np.random.choice(9,3,replace=False) # 無放回地選擇 > array([1, 2, 0]) ------------------------------------------------------------------------ # shuffle 原列表上將元素打亂(與random.shuffle相同) arr = np.arange(10) np.random.shuffle(arr) arr > array([4, 5, 0, 3, 7, 8, 9, 1, 2, 6]) ------------------------------------------------------------------------ # uniform 給定形狀產生隨機數組 np.random.uniform(0,1,[3,3,3]) > array([[[0.80239474, 0.37170323, 0.5134832 ], [0.42046889, 0.40245839, 0.0812019 ], [0.8788738 , 0.48545176, 0.73723353]], [[0.79057724, 0.80644632, 0.65966656], [0.43833643, 0.53994887, 0.46762885], [0.44472436, 0.08944074, 0.34148912]], [[0.7042795 , 0.58397044, 0.13061102], [0.22925123, 0.97745023, 0.14823085], [0.6960559 , 0.07936633, 0.91221842]]]) ------------------------------------------------------------------------ # seed 設定隨機種子(使相同參數生成的隨機數相同) np.random.seed(0) # 當seed(0)時生成如下隨機數組 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) np.random.seed(2) # send(5)時生成如下隨機數組 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) np.random.seed(0) # 再次使用send(0)會發現返回最開始的隨機數組 np.random.rand(5) > array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ]) ------------------------------------------------------------------------ # standard_normal 生成正態分佈的隨機樣本數 np.random.standard_normal([2,10]) > array([[-0.17937969, -0.69277058, 1.13782687, -0.16915725, -0.76391367, -0.4980731 , -0.36289111, 0.26396031, -0.62964191, -0.4722584 ], [-1.51336104, 1.10762468, 0.17623875, -0.94035354, 0.92959433, -1.06279492, -0.88640627, 1.92134696, -0.45978052, -1.08903444]])
np.random和Python原生的random的區別:
比較內容 | random | np.random |
---|---|---|
輸入類型 | 非空的列表類型(包括列表、字符串和元組) | 非空的列表類型(包括列表、字符串和元組)+ numpy.array類型 |
輸出維度 | 一個數或一個list(多個數) | 可指定複雜的size |
指定(a,b)範圍 | 能夠 | 整數可指定,浮點數不行,需自行轉換 |
批量輸出 | 不可 | 可。經過指定size參數 |
特定分佈 | 涵蓋了經常使用的幾個分佈; 只能單個輸出 | 幾乎涵蓋了全部分佈;可批量輸出 |
只要能把以上全部的內容掌握,數據分析這門功夫你就算是打通了任督二脈了,學起來輕鬆又愉快。
五、數據表示
全部須要處理和構建模型所需的數據類型(電子表格、圖像、音頻等),其中不少都適合在 n 維數組中表示:
表格和電子表格
表格和電子表格是二維矩陣。電子表格中的每一個工做表均可以是它本身的變量。python 中最流行的抽象是 pandas 數據幀,它實際上使用了 NumPy 並在其之上構建。
音頻和時間序列
音頻文件是樣本的一維數組。每一個樣本都是一個數字,表明音頻信號的一小部分。CD 質量的音頻每秒包含 44,100 個樣本,每一個樣本是-65535 到 65536 之間的整數。這意味着若是你有一個 10 秒的 CD 質量 WAVE 文件,你能夠將它加載到長度爲 10 * 44,100 = 441,000 的 NumPy 數組中。若是想要提取音頻的第一秒,只需將文件加載到 audio 的 NumPy 數組中,而後獲取 audio[:44100]。
如下是一段音頻文件:
時間序列數據也是如此(如股票價格隨時間變化)。
圖像
圖像是尺寸(高度 x 寬度)的像素矩陣。
若是圖像是黑白(即灰度)的,則每一個像素均可以用單個數字表示(一般在 0(黑色)和 255(白色)之間)。想要裁剪圖像左上角 10 x 10 的像素嗎?在 NumPy 寫入便可。
下圖是一個圖像文件的片斷:
若是圖像是彩色的,則每一個像素由三個數字表示——紅色、綠色和藍色。在這種狀況下,咱們須要一個三維數組(由於每一個單元格只能包含一個數字)。所以彩色圖像由尺寸爲(高 x 寬 x3)的 ndarray 表示:
六、總結
使用numpy,能夠爲咱們提供一組豐富而又靈活的數據結構,以金融的角度來看的話下面幾種類型是最重要的:
基本數據類型
在金融量化當中,整數、浮點數和字符串給咱們提供了原子數據類型
標準數據結構
元組、列表、字典和集合,這些在金融當中有許多應用領域,列表一般是最爲經常使用的
數組
說到數組確定就是今天所學習的numpy中的ndarray數組,它對於數據的處理性能更高,代碼更簡潔、方便
原文出處:https://www.cnblogs.com/guapitomjoy/p/12198706.html