Numpy 入門
Numpy簡介
- 官網鏈接:http://www.numpy.org/
- NumPy是Python語言的一個擴充程序庫。支持
高級大量的維度數組與矩陣運算
,此外也針對數組運算提供大量的數學函數庫
Numpy的基本功能
- 快速高效的多維數組對象ndarray
- 用于對數組執行元素級計算以及直接對數組執行數學運算的函數
- 用于讀寫硬盤上基于數組的數據集的工具
- 線性代數運算、傅里葉變換,以及隨機數生成
- 用于將C、C++、Fortran代碼集成到Python的工具
- 除了為Python提供快速的數組處理能力,NumPy在數據分析方面還有另外一個主要作用,即作為在算法之間傳遞數據的容器
效率對比
- 三種數據結構:list / array / numpy.array
- 三種方法求和:for / sum / numpy.sum
import timeit
from __future__ import print_function#使用for循環進行求和運算
common_for = """
for d in data:s += d
"""
#使用自帶的sum函數完成求和運算
common_sum = """
sum(data)
"""
#使用numpy求和函數進行求和運算
common_numpy_sum = """
numpy.sum(data)
"""
#list容器的讀取速度
def timeit_list(n, loops):list_setup = """
import numpy
data = [1] * {}
s = 0
""".format(n)print("")print("list-for:" ,timeit.timeit(common_for, list_setup, number = loops) )print("list-sum:" ,timeit.timeit(common_sum, list_setup, number = loops) )print("list-numpy-sum:" ,timeit.timeit(common_numpy_sum, list_setup, number = loops))#array容器的讀取速度
def timeit_array(n, loops):array_setup = """
import numpy
import array
data = array.array('L', [1] * {})
s = 0
""".format(n)print("")print("array-for:",timeit.timeit(common_for, array_setup, number = loops) )print("array-sum:",timeit.timeit(common_sum, array_setup, number = loops) )print("array-numpy-sum:",timeit.timeit(common_numpy_sum, array_setup, number = loops) )
#numpy容器的讀取速度
def timeit_numpy(n, loops):numpy_setup = """
import numpy
data = numpy.array([1] * {})
s = 0
""".format(n)print("")print("numpy-for:",timeit.timeit(common_for, numpy_setup, number = loops))print("numpy-sum:",timeit.timeit(common_sum, numpy_setup, number = loops))print("numpy-numpy-sum:",timeit.timeit(common_numpy_sum, numpy_setup, number = loops))if __name__ == '__main__':timeit_list(50000, 500)timeit_array(50000, 500)timeit_numpy(50000, 500)
list-for: 0.521558879381
list-sum: 0.0727958134364
list-numpy-sum: 0.724915150295array-for: 1.15259834089
array-sum: 0.723641693604
array-numpy-sum: 2.95501856283numpy-for: 2.08122844624
numpy-sum: 1.57353423058
numpy-numpy-sum: 0.0123528427923
*從上面的結果我們可以得到:numpy數據類型和numpy提供的數據處理函數的效率是最高的,但是把numpy的數據處理函數應用于其他的非numpy數據結構中,其效率往往不是很高。
NumPy的ndarray 創建ndarray
- 數組創建函數
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_functionprint ('使用普通一維數組生成NumPy一維數組')
data = [6, 7.5, 8, 0, 1]
arr = np.array(data)
print (arr)
print('打印元素類型')
print(arr.dtype) #提供了dtype變量查看數據的類型
print()print('使用普通二維數組生成NumPy二維數組')
data = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr = np.array(data)
print (arr)
print ('打印數組維度')
print (arr.shape)
print()print ('使用zeros/empty')
print ("np.zeros:",np.zeros(10)) # 生成包含10個0的一維數組
print ("np.zeros:",np.zeros((3, 6))) # 生成3*6的二維數組,表示數組維度的參數使用的是元組
print ("np.empty:",np.empty((2, 3, 2))) # 生成2*3*2的三維數組,所有元素未初始化。
print()print( '使用arrange生成連續元素')
print (np.arange(15)) # [0, 1, 2, ..., 14]print("使用ones_like,zeros_like和empty_like創建Numpy數組")
print("np.ones_like:",np.ones_like(np.zeros((3, 6))))
print("np.zeros_like:",np.zeros_like(np.ones((2,3))))
print("np.empty_like:",np.empty_like(np.ones((2,3))))
使用普通一維數組生成NumPy一維數組
[ 6. 7.5 8. 0. 1. ]
打印元素類型
float64使用普通二維數組生成NumPy二維數組
[[1 2 3 4][5 6 7 8]]
打印數組維度
(2L, 4L)使用zeros/empty
np.zeros: [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
np.zeros: [[ 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 0. 0. 0.][ 0. 0. 0. 0. 0. 0.]]
np.empty: [[[ 0. 0.][ 0. 0.][ 0. 0.]][[ 0. 0.][ 0. 0.][ 0. 0.]]]使用arrange生成連續元素
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
使用ones_like,zeros_like和empty_like創建Numpy數組
np.ones_like: [[ 1. 1. 1. 1. 1. 1.][ 1. 1. 1. 1. 1. 1.][ 1. 1. 1. 1. 1. 1.]]
np.zeros_like: [[ 0. 0. 0.][ 0. 0. 0.]]
np.empty_like: [[ 1. 1. 1.][ 1. 1. 1.]]
NumPy的ndarray NumPy數據類型
- NumPy數據類型 I
- NumPy數據類型 II
- 創建ndarray時指定dtype類型
- 使用astype顯示轉換類型
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_functionprint ('生成數組時指定數據類型')
arr = np.array([1, 2, 3], dtype = np.float64) # 使用dtype關鍵字指定數據的類型
print (arr.dtype)
arr = np.array([1, 2, 3], dtype = np.int32)
print (arr.dtype)
print()print ('使用astype復制數組并轉換數據類型')
int_arr = np.array([1, 2, 3, 4, 5])
float_arr = int_arr.astype(np.float)#使用astype轉換數據的類型
print (int_arr.dtype)
print (float_arr.dtype)
print()print ('使用astype將float轉換為int時小數部分被舍棄')
float_arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
int_arr = float_arr.astype(dtype = np.int)
print (int_arr)
print()print ('使用astype把字符串轉換為數組,如果失敗拋出異常。')
str_arr = np.array(['1.25', '-9.6', '42'], dtype = np.string_)#一定要注意后面的下劃線
float_arr = str_arr.astype(dtype = np.float)
print (float_arr)
print()print( 'astype使用其它數組的數據類型作為參數')
int_arr = np.arange(10)
float_arr = np.array([.23, 0.270, .357, 0.44, 0.5], dtype = np.float64)
print (int_arr.astype(float_arr.dtype))
print (int_arr[0], int_arr[1]) # astype做了復制,數組本身不變。
生成數組時指定數據類型
float64
int32使用astype復制數組并轉換數據類型
int32
float64使用astype將float轉換為int時小數部分被舍棄
[ 3 -1 -2 0 12 10]使用astype把字符串轉換為數組,如果失敗拋出異常。
[ 1.25 -9.6 42. ]astype使用其它數組的數據類型作為參數
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
0 1
NumPy的ndarray 數組和標量之間的運算
- 不用編寫循環即可對數據執行批量運算
- 大小相等的數組之間的任何算術運算都會將運算應用到元素級
- 數組與標量的算術運算也會將那個標量值傳播到各個元素
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_function# 數組乘法/減法,對應元素相乘/相減。
arr = np.array([[1.0, 2.0, 3.0], [4., 5., 6.]])
print ('數組乘法:',arr * arr) #對應元素相乘
print ('數組減法:',arr - arr) #對應元素相減
print()# 標量操作作用在數組的每個元素上(廣播作用)
arr = np.array([[1.0, 2.0, 3.0], [4., 5., 6.]])
print ("數組除法:",1 / arr)#對數組中的每個元素最除法
print ("開根號:",arr ** 0.5) # 開根號
print ("數組加法:",arr + 0.5) # 加法
數組乘法: [[ 1. 4. 9.][ 16. 25. 36.]]
數組減法: [[ 0. 0. 0.][ 0. 0. 0.]]數組除法: [[ 1. 0.5 0.33333333][ 0.25 0.2 0.16666667]]
開根號: [[ 1. 1.41421356 1.73205081][ 2. 2.23606798 2.44948974]]
數組加法: [[ 1.5 2.5 3.5][ 4.5 5.5 6.5]]
NumPy的ndarray 基本的索引和切片
- 索引原理
- 切片原理
# -*- coding: utf-8 -*-import numpy as np
from __future__ import print_function# 通過索引訪問二維數組某一行或某個元素
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("數組的維度為:" , arr.shape)
print (arr[2]) #數組的第3行
print (arr[0][2]) #數組的第一行第三列的元素
print (arr[0, 2]) # 普通Python數組不能用。數組的diy
print()# 對更高維數組的訪問和操作
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr)
print("數組的維度為:" , arr.shape)
print (arr[0]) # 結果是個2維數組:[[1,2,3],[4,5,6]],相當于減去了一個中括號,然后選獨立的部分
print (arr[1, 0]) # 結果是個1維數組:[7,8,9]
old_values = arr[0].copy() # 復制arr[0]的值(此處必須使用copy方法,進行完全的復制,這是一個坑)
arr[0] = 42 # 把arr[0]所有的元素都設置為同一個值
print (arr)
arr[0] = old_values # 把原來的數組寫回去
print (arr)
print()print ('使用切片訪問和操作數組')
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print("數組的維度為:" , arr.shape)
print (arr[1:6]) # 打印元素arr[1]到arr[5]arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print (arr[:2]) # 打印第1、2行
print (arr[:2, 1:]) # 打印第1、2行,第2、3列
print (arr[:, :1]) # 打印第一列的所有元素
arr[:2, 1:] = 0 # 第1、2行,第2、3列的元素設置為0
print (arr)
數組的維度為: (3L, 3L)
[7 8 9]
3
3[[[ 1 2 3][ 4 5 6]][[ 7 8 9][10 11 12]]]
數組的維度為: (2L, 2L, 3L)
[[1 2 3][4 5 6]]
[7 8 9]
[[[42 42 42][42 42 42]][[ 7 8 9][10 11 12]]]
[[[ 1 2 3][ 4 5 6]][[ 7 8 9][10 11 12]]]使用切片訪問和操作數組
數組的維度為: (10L,)
[2 3 4 5 6]
[[1 2 3][4 5 6]]
[[2 3][5 6]]
[[1][4][7]]
[[1 0 0][4 0 0][7 8 9]]
數組的索引和切片非常重要:
- 看一個numpy的數組是幾維的,則可以數數組表示中中括號的最大個數,如果最大的個數為3個,則該數組為3維
- 切片中的[a,b]是一個左閉右開的區間,數組的初始坐標都從0開始計算
- 多維數組可以看成多個低位數組的行排列。
NumPy的ndarray 布爾型索引
- 布爾型數組的長度必須跟被索引的軸長度一致
- 可以將布爾型數組跟切片、整數(或整數序列)混合使用
from __future__ import print_function
import numpy as np
import numpy.random as np_randomprint ('使用布爾數組作為索引')
name_arr = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
rnd_arr = np_random.randn(7, 4) # 隨機7*4數組
print (rnd_arr)
print (name_arr == 'Bob') # 返回布爾數組,元素等于'Bob'為True,否則False。
print (rnd_arr[name_arr == 'Bob']) # 利用布爾數組選擇行,選出數組的第0行和第3行
print (rnd_arr[name_arr == 'Bob', :2]) # 增加限制打印列的范圍,選出數組的第0行和第3行的第0列和第1列
print (rnd_arr[~(name_arr == 'Bob')]) # 對布爾數組的內容取反
mask_arr = (name_arr == 'Bob') | (name_arr == 'Will') # 邏輯運算混合結果
print (rnd_arr[mask_arr])
rnd_arr[name_arr != 'Joe'] = 7 # 先布爾數組選擇行,然后把每行的元素設置為7。
print (rnd_arr)
使用布爾數組作為索引
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][ 0.52151894 -0.06591568 -1.13705598 0.30621352][-2.15443164 -0.72205865 0.4932395 -0.91993207][-0.50711626 2.11309111 -1.67907697 0.19700825][ 1.56799018 1.23573277 -1.57973114 1.20070367][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
[ True False False True False False False]
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][-0.50711626 2.11309111 -1.67907697 0.19700825]]
[[-0.1084202 -0.40555507][-0.50711626 2.11309111]]
[[ 0.52151894 -0.06591568 -1.13705598 0.30621352][-2.15443164 -0.72205865 0.4932395 -0.91993207][ 1.56799018 1.23573277 -1.57973114 1.20070367][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
[[-0.1084202 -0.40555507 -0.42840017 -1.21241416][-2.15443164 -0.72205865 0.4932395 -0.91993207][-0.50711626 2.11309111 -1.67907697 0.19700825][ 1.56799018 1.23573277 -1.57973114 1.20070367]]
[[ 7. 7. 7. 7. ][ 0.52151894 -0.06591568 -1.13705598 0.30621352][ 7. 7. 7. 7. ][ 7. 7. 7. 7. ][ 7. 7. 7. 7. ][ 0.36692194 -0.1980408 0.02920299 1.40526864][ 1.38148029 0.95975349 0.19451545 -1.22338701]]
NumPy的ndarray 花式索引
- 花式索引(Fancy indexing)是一個NumPy術語,它指的是利用整數數組進行索引
- 一次傳入多個索引數組會有一點特別。它返回的是一個一維數組,其中的元素對應各個索引元組
# -*- coding: utf-8 -*-import numpy as npprint ('Fancy Indexing: 使用整數數組作為索引')
arr = np.empty((8, 4))
for i in range(8):arr[i] = i
print (arr)
print()
print (arr[[4, 3, 0, 6]]) # 打印arr[4]、arr[3]、arr[0]和arr[6]。
print()
print (arr[[-3, -5, -7]]) # 打印arr[3](8-5)、arr[5](8-3)和arr[1](8-7)行
print()
arr = np.arange(32).reshape((8, 4)) # 通過reshape變換成二維數組
print(arr)
print()
print (arr[[1, 5, 7, 2], [0, 3, 1, 2]]) # 打印arr[1, 0]、arr[5, 3],arr[7, 1]和arr[2, 2]
print()
print (arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] ) # 1572行的0312列
print()
print (arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]) # 可讀性更好的寫法
Fancy Indexing: 使用整數數組作為索引
[[ 0. 0. 0. 0.][ 1. 1. 1. 1.][ 2. 2. 2. 2.][ 3. 3. 3. 3.][ 4. 4. 4. 4.][ 5. 5. 5. 5.][ 6. 6. 6. 6.][ 7. 7. 7. 7.]][[ 4. 4. 4. 4.][ 3. 3. 3. 3.][ 0. 0. 0. 0.][ 6. 6. 6. 6.]][[ 5. 5. 5. 5.][ 3. 3. 3. 3.][ 1. 1. 1. 1.]][[ 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 30 31]][ 4 23 29 10][[ 4 7 5 6][20 23 21 22][28 31 29 30][ 8 11 9 10]][[ 4 7 5 6][20 23 21 22][28 31 29 30][ 8 11 9 10]]
NumPy的ndarray 數組轉置和軸對換
- 一維/二維數組轉置
- 高維數組軸對換
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('轉置矩陣')
arr = np.arange(15).reshape((3, 5))
print (arr)
print (arr.T)
print()print ('轉置矩陣做點積')
arr = np_random.randn(6, 3)
print (np.dot(arr.T, arr))
print()print ('高維矩陣轉換')
arr = np.arange(16).reshape((2, 2, 4))
print (arr)
'''
詳細解釋:
arr數組的內容為
- a[0][0] = [0, 1, 2, 3]
- a[0][1] = [4, 5, 6, 7]
- a[1][0] = [8, 9, 10, 11]
- a[1][1] = [12, 13, 14, 15]
transpose的參數為坐標,正常順序為(0, 1, 2, ... , n - 1),
現在傳入的為(1, 0, 2)代表a[x][y][z] = a[y][x][z],第0個和第1個坐標互換。
- a'[0][0] = a[0][0] = [0, 1, 2, 3]
- a'[0][1] = a[1][0] = [8, 9, 10, 11]
- a'[1][0] = a[0][1] = [4, 5, 6, 7]
- a'[1][1] = a[1][1] = [12, 13, 14, 15]
'''
print (arr.transpose((1, 0, 2)))
print (arr.swapaxes(1, 2)) # 直接交換第1和第2個坐標
轉置矩陣
[[ 0 1 2 3 4][ 5 6 7 8 9][10 11 12 13 14]]
[[ 0 5 10][ 1 6 11][ 2 7 12][ 3 8 13][ 4 9 14]]轉置矩陣做點積
[[ 6.36174171 2.42894214 0.43029091][ 2.42894214 1.62972705 -0.47956574][ 0.43029091 -0.47956574 8.71542488]]高維矩陣轉換
[[[ 0 1 2 3][ 4 5 6 7]][[ 8 9 10 11][12 13 14 15]]]
[[[ 0 1 2 3][ 8 9 10 11]][[ 4 5 6 7][12 13 14 15]]]
[[[ 0 4][ 1 5][ 2 6][ 3 7]][[ 8 12][ 9 13][10 14][11 15]]]
NumPy的ndarray 快速的元素級數組函數
- 一元函數 I
- 一元函數 II
- 二元函數 I
- 二元函數 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint("一元數組I")print("計算整數、浮點數或復數的絕對值")
a = - np.arange(32).reshape((4,8))
print(abs(a))
# print(fabs(a))print ('求平方根')
arr = np.arange(10)
print (np.sqrt(arr))
print()print("計算各元素的平方")
arr = np.empty((8,3))
for i in range(8):arr[i] = i
print(arr)print ('數組比較')
x = np_random.randn(8)
y = np_random.randn(8)
print (x)
print (y)
print (np.maximum(x, y))
print()print ('使用modf函數把浮點數分解成整數和小數部分')
arr = np_random.randn(7) * 5 # 統一乘5
print (np.modf(arr))
一元數組I
計算整數、浮點數或復數的絕對值
[[ 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 30 31]]
求平方根
[ 0. 1. 1.41421356 1.73205081 2. 2.236067982.44948974 2.64575131 2.82842712 3. ]計算各元素的平方
[[ 0. 0. 0.][ 1. 1. 1.][ 2. 2. 2.][ 3. 3. 3.][ 4. 4. 4.][ 5. 5. 5.][ 6. 6. 6.][ 7. 7. 7.]]
數組比較
[-0.68111525 0.14478485 -1.90946169 -1.44911281 0.83112239 -0.70184092-0.87512769 0.86081927]
[-1.76259424 -0.23016572 0.3511254 -1.44010152 0.27544984 0.27675796-1.0203264 -1.95418324]
[-0.68111525 0.14478485 0.3511254 -1.44010152 0.83112239 0.27675796-0.87512769 0.86081927]使用modf函數把浮點數分解成整數和小數部分
(array([-0.5637991 , -0.97362809, -0.35885139, 0.52156623, 0.31868237,-0.62290837, 0.18592416]), array([-4., -6., -0., 4., 0., -2., 3.]))
利用數組進行數據處理
- NumPy數組使你可以將許多種數據處理任務表述為簡潔的數組表達式(否則需要編寫循環)。用數組表達式代替循環的做法,通常被稱為矢量化。
- 矢量化數組運算要比等價的純Python方式快上一兩個數量級
# -*- coding: utf-8 -*-from __future__ import print_function
import matplotlib.pyplot as plt
import numpy as np
import pylabpoints = np.arange(-5, 5, 0.01) # 生成100個點
xs, ys = np.meshgrid(points, points) # xs, ys互為轉置矩陣
print (xs)
print (ys)
z = np.sqrt(xs ** 2 + ys ** 2)
print (z)
# 畫圖
plt.imshow(z, cmap = plt.cm.gray);
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
pylab.show()
利用數組進行數據處理 將條件邏輯表述為數組運算
- 列表推導的局限性
- 純Python代碼,速度不夠快
- 無法應用于高維數組
- where和where的嵌套
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random'''
關于zip函數的一點解釋,zip可以接受任意多參數,然后重新組合成1個tuple列表。
zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
返回結果:[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
'''
print ('通過真值表選擇元素')
x_arr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
y_arr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = [(x if c else y) for x, y, c in zip(x_arr, y_arr, cond)] # 通過列表推到實現
print (result)
print (np.where(cond, x_arr, y_arr)) # 使用NumPy的where函數
print()print ('更多where的例子')
arr = np_random.randn(4, 4)
print (arr)
print (np.where(arr > 0, 2, -2)) #數組中大于0的值,賦值為2,小于0的賦值為-2
print (np.where(arr > 0, 2, arr)) #數組中大于0的值,賦值為2,小于0的不變
print()print ('where嵌套')
cond_1 = np.array([True, False, True, True, False])
cond_2 = np.array([False, True, False, True, False])
# 傳統代碼如下
result = []
for i in xrange(len(cond)):if cond_1[i] and cond_2[i]:result.append(0)elif cond_1[i]:result.append(1)elif cond_2[i]:result.append(2)else:result.append(3)
print (result)
# np版本代碼
result = np.where(cond_1 & cond_2, 0, \np.where(cond_1, 1, np.where(cond_2, 2, 3)))
print (result)
通過真值表選擇元素
[1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]
[ 1.1 2.2 1.3 1.4 2.5]更多where的例子
[[-0.79654157 1.3048699 -0.16649545 -0.67927283][ 1.03154654 -0.84729219 0.88878329 1.22445457][ 0.21591511 -1.76778359 0.64909628 0.9290586 ][-1.07820837 0.77882286 -0.85592141 0.73408195]]
[[-2 2 -2 -2][ 2 -2 2 2][ 2 -2 2 2][-2 2 -2 2]]
[[-0.79654157 2. -0.16649545 -0.67927283][ 2. -0.84729219 2. 2. ][ 2. -1.76778359 2. 2. ][-1.07820837 2. -0.85592141 2. ]]where嵌套
[1, 2, 1, 0, 3]
[1 2 1 0 3]
利用數組進行數據處理 數學和統計方法
- 數學和統計方法
- 標準差和方差的解釋
- cumsum和cumprod的解釋
- 帶axis參數的統計函數
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('求和,求平均')
arr = np.random.randn(5, 4)
print (arr)
print (arr.mean())
print (arr.sum())
print (arr.mean(axis = 1)) # 對每一行的元素求平均 (0表示列 , 1表示行)
print (arr.sum(0)) # 對每一列元素求和,axis可以省略。
print()'''
cumsum:
- 按列操作:a[i][j] += a[i - 1][j]
- 按行操作:a[i][j] *= a[i][j - 1]
cumprod:
- 按列操作:a[i][j] += a[i - 1][j]
- 按行操作:a[i][j] *= a[i][j - 1]
'''
print ('cunsum和cumprod函數演示')
arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
print (arr.cumsum(0))#列不變,按行操作,第i行等于第i-1行+第i行
print (arr.cumprod(1))#行不變,按列操作,第j列等于第j-1列*第j列
求和,求平均
[[ 0.26455591 0.24469854 0.35609714 -0.91358351][-0.06096831 -1.4540408 1.52873578 -1.04853165][ 0.13539534 -0.57258895 0.01197242 -0.16440243][-0.37880532 -0.5595963 0.61614963 0.40114372][ 1.02586237 0.51157099 0.51307014 0.06042945]]
0.0258582086869
0.517164173737
[-0.01205798 -0.25870124 -0.1474059 0.01972293 0.52773324]
[ 0.98603999 -1.82995651 3.02602511 -1.66494442]cunsum和cumprod函數演示
[[ 0 1 2][ 3 5 7][ 9 12 15]]
[[ 0 0 0][ 3 12 60][ 6 42 336]]
利用數組進行數據處理 用于布爾型數組的方法
- sum對True值計數
- any和all測試布爾型數組,對于非布爾型數組,所有非0元素將會被當做True
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('對正數求和')
arr = np_random.randn(100)
print("數組為:" , arr)
print ((arr > 0).sum())
print()print ('對數組邏輯操作')
bools = np.array([False, False, True, False])
print (bools.any()) # 有一個為True則返回True
print (bools.all()) # 有一個為False則返回False
對正數求和
數組為: [-0.67957765 0.17922628 0.81893223 1.51839207 -0.53998528 -0.061346690.26828107 0.49541898 0.3968868 1.48527375 -0.92795078 0.67722850.92645474 0.82941435 -1.55900369 -0.9505581 0.55135723 -0.24448502-0.89383558 -1.04803647 1.46630771 1.05768561 -1.31654583 -0.793245111.24940464 -0.35685884 0.2880603 1.79418786 -0.06005563 -0.326561910.61529929 1.18118605 -0.67298437 -0.18722625 0.67770887 -1.855256140.21878993 0.35457737 1.26314661 -1.38037944 1.83993354 -0.76711544-0.36366676 0.4834541 -0.3258269 -0.50041094 -0.11865619 0.182630250.71411782 0.66851825 -0.53817733 0.29773314 -0.32270224 -0.28514864-0.88821182 -0.27463386 0.3208152 -0.63070493 -1.50305558 1.04202097-0.55430861 0.5475183 -0.29936811 -0.8214571 -0.05786574 0.19635782-2.4263667 0.23870753 -0.32306864 2.20755471 0.62571506 -1.620709410.03456916 0.73668574 -0.47187531 -1.40560797 0.86782166 -0.620637020.34219792 -1.06724602 -1.25501497 -0.59017057 0.33234826 -0.33625352-0.10762397 -0.14479564 -0.85080006 -0.1615957 0.00796442 1.51127179-1.50552389 -0.27143849 0.04650197 -0.17451162 -0.01494695 0.532787152.0052779 1.68621344 0.43084895 -0.86445014]
47對數組邏輯操作
True
False
利用數組進行數據處理 排序
- 直接排序
- 指定軸排序
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('一維數組排序')
arr = np_random.randn(8)
print("排序前:",arr)
arr.sort() #默認為從小到大排序
print ("排序后:",arr)
print()print ('二維數組排序')
arr = np_random.randn(5, 3)
print (arr)
arr.sort(1) # 對每一行元素做排序
print (arr)print ('找位置在5%的數字')
large_arr = np_random.randn(1000)
large_arr.sort()
print (large_arr[int(0.05 * len(large_arr))])
一維數組排序
排序前: [-1.42173589 0.48630163 -0.66291646 -0.45981918 1.9129553 1.226950490.82006022 0.92006356]
排序后: [-1.42173589 -0.66291646 -0.45981918 0.48630163 0.82006022 0.920063561.22695049 1.9129553 ]二維數組排序
[[-1.19629529 0.31347271 -1.76425575][ 0.140376 0.27033496 -0.61144276][-0.62964274 -0.19658808 -0.00377922][ 0.82857078 -0.77745588 -0.39493397][ 1.87901812 -0.03795931 0.15201365]]
[[-1.76425575 -1.19629529 0.31347271][-0.61144276 0.140376 0.27033496][-0.62964274 -0.19658808 -0.00377922][-0.77745588 -0.39493397 0.82857078][-0.03795931 0.15201365 1.87901812]]
找位置在5%的數字
-1.75964266014
利用數組進行數據處理 去重以及其它集合運算
- 去重以及其它集合運算
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint( '用unique函數去重')
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
print (sorted(set(names))) # 傳統Python做法:先轉為集合,去重后,在排序
print (np.unique(names))
ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
print (np.unique(ints))
print()print("計算x和y中的公共元素")
valuse = np.array([1,4,6,8,0,1,4,5])
print(np.intersect1d(values,[1,5,6]))print( '查找數組元素是否在另一數組')
values = np.array([6, 0, 0, 3, 2, 5, 6])
print (np.in1d(values, [2, 3, 6]))#判斷數組value中的值是否在數組[2,3,6]中,如果在,則為true,否則為false
用unique函數去重
['Bob', 'Joe', 'Will']
['Bob' 'Joe' 'Will']
[1 2 3 4]計算x和y中的公共元素
[5 6]
查找數組元素是否在另一數組
[ True False False True True False True]
數組文件的輸入輸出
- 將數組以二進制格式保存到磁盤
- 存取文本文件
# -*- coding: utf-8 -*-import numpy as npprint ('數組文件讀寫')
arr = np.arange(10)
np.save('some_array', arr)
print (np.load('some_array.npy'))
print()print( '多個數組壓縮存儲')
np.savez('array_archive.npz', a = arr, b = arr)
arch = np.load('array_archive.npz')
print (arch['b'])
數組文件讀寫
[0 1 2 3 4 5 6 7 8 9]多個數組壓縮存儲
[0 1 2 3 4 5 6 7 8 9]
# -*- coding: utf-8 -*-import numpy as npprint ('讀取csv文件做為數組')
arr = np.loadtxt('array_ex.txt', delimiter = ',')
print (arr)
線性代數
- 常用的numpy.linalg函數 I
- 常用的numpy.linalg函數 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random
from numpy.linalg import inv, qrprint ('矩陣乘法')
x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
print (x.dot(y))
print (np.dot(x, np.ones(3)))
x = np_random.randn(5, 5)
print()print( '矩陣求逆')
mat = x.T.dot(x)
print( inv(mat)) # 矩陣求逆
print (mat.dot(inv(mat))) # 與逆矩陣相乘,得到單位矩陣。
print()print ('矩陣消元')
print (mat)
q, r = qr(mat)
print (q)
print (r)
# TODO: http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.qr.html q代表什么矩陣?
矩陣乘法
[[ 28. 64.][ 67. 181.]]
[ 6. 15.]矩陣求逆
[[ 0.5011485 0.30366035 0.02944988 0.10182832 0.37384833][ 0.30366035 1.10386855 0.51472706 0.14750528 0.33597911][ 0.02944988 0.51472706 0.49264089 0.0648786 0.02335427][ 0.10182832 0.14750528 0.0648786 0.24308276 -0.06829375][ 0.37384833 0.33597911 0.02335427 -0.06829375 0.76240877]]
[[ 1.00000000e+00 3.47790860e-16 8.91056239e-18 3.96778168e-17-2.44764394e-17][ 2.29383400e-17 1.00000000e+00 -6.05299206e-17 4.07325720e-172.32749172e-16][ -1.66416098e-17 -1.80279523e-17 1.00000000e+00 -4.81508104e-17-1.48983014e-16][ 3.02073179e-16 6.79592724e-17 -2.87171290e-17 1.00000000e+00-9.96169938e-17][ -2.42778368e-17 -8.66789085e-18 -5.19194405e-17 -3.07066395e-171.00000000e+00]]矩陣消元
[[ 4.32328254 -0.63693392 0.79671674 -2.21655667 -2.06219977][-0.63693392 2.68135504 -2.60228948 -0.91045864 -0.87114247][ 0.79671674 -2.60228948 4.64737 0.18198227 0.63005045][-2.21655667 -0.91045864 0.18198227 6.11670728 2.03045137][-2.06219977 -0.87114247 0.63005045 2.03045137 2.86931167]]
[[-0.80424283 0.05803869 0.31139518 -0.29376817 0.40811553][ 0.11848625 -0.6616017 -0.46781842 -0.44143639 0.36677518][-0.14821 0.63785055 -0.72732656 -0.20378064 0.02549494][ 0.4123371 0.28244792 0.37835796 -0.77555677 -0.07455361][ 0.38362271 0.26885784 0.10963713 0.27535309 0.83229168]]
[[-5.37559352 0.50603266 -1.32113627 4.94887402 3.39987476][ 0. -3.96219829 4.95304159 2.86334648 2.20347373][ 0. 0. -1.77673158 2.14026146 0.38994553][ 0. 0. 0. -3.16878375 0.07731411][ 0. 0. 0. 0. 1.09166069]]
隨機數生成
- 部分numpy.random函數 I
- 部分numpy.random函數 II
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_random
from random import normalvariateprint ('正態分布隨機數')
samples = np.random.normal(size=(4, 4))
print (samples)print ('批量按正態分布生成0到1的隨機數')
N = 10
print( [normalvariate(0, 1) for _ in xrange(N)])
print (np.random.normal(size = N)) # 與上面代碼等價
正態分布隨機數
[[-0.50544264 -0.82576933 1.89526245 -0.58707003][ 0.2252303 -0.33877777 -0.51077759 -0.34970251][-0.47528039 0.49921574 0.94502307 -0.2377654 ][-0.36301675 -0.76251246 1.76277718 0.42690543]]
批量按正態分布生成0到1的隨機數
[-1.0186591774950984, 1.866210983292114, -1.1265355424761359, 1.2576651018422442, 0.5304683236918599, -2.907445702261537, 0.4475662133447387, -1.1263633248787712, -0.46554861570035416, 0.8651894338485295]
[-0.29615892 0.15133984 -0.05640947 1.63244238 1.3805192 1.33271080.56834895 -0.15348624 -0.27670743 0.15896747]
高級應用 數組重塑
- reshape重塑數組
- -1自動推導維度大小
# -*- coding: utf-8 -*-import numpy as npprint ("將一維數組轉換為二維數組")
arr = np.arange(8)
print (arr.reshape((4, 2)))
print (arr.reshape((4, 2)).reshape((2, 4))) # 支持鏈式操作
print()print ("維度大小自動推導")
arr = np.arange(15)
print (arr.reshape((5, -1)))
print()print ("獲取維度信息并應用")
other_arr = np.ones((3, 5))
print (other_arr.shape)
print (arr.reshape(other_arr.shape))
print()print ("高維數組拉平")
arr = np.arange(15).reshape((5, 3))
print (arr.ravel())
將一維數組轉換為二維數組
[[0 1][2 3][4 5][6 7]]
[[0 1 2 3][4 5 6 7]]維度大小自動推導
[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11][12 13 14]]獲取維度信息并應用
(3L, 5L)
[[ 0 1 2 3 4][ 5 6 7 8 9][10 11 12 13 14]]高維數組拉平
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
高級應用 數組的合并和拆分
- 數組連接函數
- _r對象
- _c對象
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint( '連接兩個二維數組')
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
print (np.concatenate([arr1, arr2], axis = 0)) # 將2個數組按上下進行堆疊(列形式),然后去掉中括號
print (np.concatenate([arr1, arr2], axis = 1)) # 將2個數組按作業進行排布(行形式),然后去掉中括號
print()# 所謂堆疊,參考疊盤子。。。連接的另一種表述
print ('垂直stack與水平stack')
print (np.vstack((arr1, arr2))) # 垂直堆疊,將2個數組按上下進行堆疊(列形式),然后去掉中括號
print (np.hstack((arr1, arr2))) # 水平堆疊,將2個數組按作業進行排布(行形式),然后去掉中括號
print()print ('拆分數組')
arr = np_random.randn(5, 5)
print (arr)
print ('水平拆分')
first, second, third = np.split(arr, [1, 3], axis = 0) # 列不變,按行拆分
print ('first')
print (first)
print( 'second')
print (second)
print ('third')
print (third)
print ('垂直拆分')
first, second, third = np.split(arr, [1, 3], axis = 1)# 行不變,按列拆分
print ('first')
print (first)
print ('second')
print (second)
print( 'third')
print (third)
print()# 堆疊輔助類
arr = np.arange(6)
arr1 = arr.reshape((3, 2))
arr2 = np_random.randn(3, 2)
print ('r_用于按行堆疊')
print (np.r_[arr1, arr2])
print ('c_用于按列堆疊')
print (np.c_[np.r_[arr1, arr2], arr])
print ('切片直接轉為數組')
print (np.c_[1:6, -10:-5])
連接兩個二維數組
[[ 1 2 3][ 4 5 6][ 7 8 9][10 11 12]]
[[ 1 2 3 7 8 9][ 4 5 6 10 11 12]]垂直stack與水平stack
[[ 1 2 3][ 4 5 6][ 7 8 9][10 11 12]]
[[ 1 2 3 7 8 9][ 4 5 6 10 11 12]]拆分數組
[[ 1.89364796 0.90294454 -1.04449259 0.05542727 -1.95040133][ 0.61216323 -0.04858817 0.62079075 2.14728789 -1.64469211][ 0.80412986 -1.1504998 0.72143456 1.2071584 0.28430334][ 0.83783665 0.46357796 -1.03665112 0.63458637 -1.47938356][-0.14603724 -1.20880463 0.37298991 -0.91002865 -0.86368792]]
水平拆分
first
[[ 1.89364796 0.90294454 -1.04449259 0.05542727 -1.95040133]]
second
[[ 0.61216323 -0.04858817 0.62079075 2.14728789 -1.64469211][ 0.80412986 -1.1504998 0.72143456 1.2071584 0.28430334]]
third
[[ 0.83783665 0.46357796 -1.03665112 0.63458637 -1.47938356][-0.14603724 -1.20880463 0.37298991 -0.91002865 -0.86368792]]
垂直拆分
first
[[ 1.89364796][ 0.61216323][ 0.80412986][ 0.83783665][-0.14603724]]
second
[[ 0.90294454 -1.04449259][-0.04858817 0.62079075][-1.1504998 0.72143456][ 0.46357796 -1.03665112][-1.20880463 0.37298991]]
third
[[ 0.05542727 -1.95040133][ 2.14728789 -1.64469211][ 1.2071584 0.28430334][ 0.63458637 -1.47938356][-0.91002865 -0.86368792]]r_用于按行堆疊
[[ 0. 1. ][ 2. 3. ][ 4. 5. ][ 0.16991136 -1.43876481][-0.98143743 -1.05678896][-0.19718503 0.13712377]]
c_用于按列堆疊
[[ 0. 1. 0. ][ 2. 3. 1. ][ 4. 5. 2. ][ 0.16991136 -1.43876481 3. ][-0.98143743 -1.05678896 4. ][-0.19718503 0.13712377 5. ]]
切片直接轉為數組
[[ 1 -10][ 2 -9][ 3 -8][ 4 -7][ 5 -6]]
高級應用 元素的重復操作
- _tile
- _repeat
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('Repeat: 按元素')
arr = np.arange(3)
print (arr.repeat(3)) #以整個數組為對象。進行復制
print (arr.repeat([2, 3, 4])) # 3個元素,分別復制2, 3, 4次。長度要匹配!
print()print ('Repeat,指定軸')
arr = np_random.randn(2, 2)
print (arr)
print (arr.repeat(2, axis = 0)) # 按行repeat
print (arr.repeat(2, axis = 1)) # 按列repeat
print (arr.repeat(2, axis = 0)) # 按行repeat
print()print ('Tile: 參考貼瓷磚')#元素級別的復制
print (np.tile(arr, 2))
print (np.tile(arr, (2, 3))) # 指定每個軸的tile次數
Repeat: 按元素
[0 0 0 1 1 1 2 2 2]
[0 0 1 1 1 2 2 2 2]Repeat,指定軸
[[-0.09641823 -2.30892488][-0.47084845 -0.85517063]]
[[-0.09641823 -2.30892488][-0.09641823 -2.30892488][-0.47084845 -0.85517063][-0.47084845 -0.85517063]]
[[-0.09641823 -0.09641823 -2.30892488 -2.30892488][-0.47084845 -0.47084845 -0.85517063 -0.85517063]]
[[-0.09641823 -2.30892488][-0.09641823 -2.30892488][-0.47084845 -0.85517063][-0.47084845 -0.85517063]]Tile: 參考貼瓷磚
[[-0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063]]
[[-0.09641823 -2.30892488 -0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063 -0.47084845 -0.85517063][-0.09641823 -2.30892488 -0.09641823 -2.30892488 -0.09641823 -2.30892488][-0.47084845 -0.85517063 -0.47084845 -0.85517063 -0.47084845 -0.85517063]]
高級應用 花式索引的等價函數
- take
- put
# -*- coding: utf-8 -*-import numpy as np
import numpy.random as np_randomprint ('Fancy Indexing例子代碼')
arr = np.arange(10) * 100
inds = [7, 1, 2, 6]
print (arr[inds])
print()print ('使用take')
print (arr.take(inds))
print()print ('使用put更新內容')
arr.put(inds, 50)
print (arr)
arr.put(inds, [70, 10, 20, 60])
print (arr)
print()print ('take,指定軸')
arr = np_random.randn(2, 4)
inds = [2, 0, 2, 1]
print (arr)
print (arr.take(inds, axis = 1) ) # 按列take
Fancy Indexing例子代碼
[700 100 200 600]使用take
[700 100 200 600]使用put更新內容
[ 0 50 50 300 400 500 50 50 800 900]
[ 0 10 20 300 400 500 60 70 800 900]take,指定軸
[[-0.02673792 -0.07054738 -1.14709723 0.53862843][ 1.36231019 -0.95801917 1.33658699 0.36900439]]
[[-1.14709723 -0.02673792 -1.14709723 -0.07054738][ 1.33658699 1.36231019 1.33658699 -0.95801917]]