numpy 使用

1. 什么是 NumPy?

  • NumPy是一個功能強大的Python庫,主要用于對多維數(shù)組執(zhí)行計算者冤。NumPy這個詞來源于兩個單詞-- Numerical和Python.NumPy提供了大量的庫函數(shù)和操作兴垦,可以幫助程序員輕松地進行數(shù)值計算温兼。這類數(shù)值計算廣泛用于以下任務:
    • 機器學習模型:在編寫機器學習算法時派近,需要對矩陣進行各種數(shù)值計算。例如矩陣乘法、換位酗洒、加法等。NumPy提供了一個非常好的庫缔逛,用于簡單(在編寫代碼方面)和快速(在速度方面)計算遭垛。NumPy數(shù)組用于存儲訓練數(shù)據(jù)和機器學習模型的參數(shù)。
    • 圖像處理和計算機圖形學:計算機中的圖像表示為多維數(shù)字數(shù)組节槐。NumPy成為同樣情況下最自然的選擇搀庶。實際上,NumPy提供了一些優(yōu)秀的庫函數(shù)來快速處理圖像铜异。例如哥倔,鏡像圖像、按特定角度旋轉圖像等揍庄。
    • 數(shù)學任務:NumPy對于執(zhí)行各種數(shù)學任務非常有用咆蒿,如數(shù)值積分、微分蚂子、內(nèi)插沃测、外推等。因此食茎,當涉及到數(shù)學任務時蒂破,它形成了一種基于Python的MATLAB的快速替代。

2. 我們?yōu)槭裁匆莆誑umPy

  • 人們有時會說别渔,與C++這種低級語言相比附迷,Python以運行速度為代價改善了開發(fā)時間和效率。幸運的是哎媚,有一些方法可以在不犧牲易用性的情況下加速Python中的操作運行時喇伯。適用于快速數(shù)值運算的一個選項是NumPy,它當之無愧地將自己稱為使用Python進行科學計算的基本軟件包抄伍。
  • 通常艘刚,矢量化數(shù)組操作通常比其純Python等價物快一個或兩個(或更多)數(shù)量級,在任何類型的數(shù)值計算中都具有最大的影響截珍。
  • 在Python中循環(huán)數(shù)組或任何數(shù)據(jù)結構時攀甚,會涉及很多開銷。 NumPy中的向量化操作將內(nèi)部循環(huán)委托給高度優(yōu)化的C和Fortran函數(shù)岗喉,從而實現(xiàn)更清晰秋度,更快速的Python代碼。

3. NumPy 簡單實用

3.1 使用方式?

可以使用如下的方式來安裝numpy庫:
pip install numpy
根據(jù)慣例钱床,使用numpy庫的導入方式為:
import numpy as np
在導入之后荚斯,我們可以通過:
np.__version__
來查看Numpyu庫的版本信息。

import numpy as np 
print(np.__version__)
運行結果
1.16.4

3.2 創(chuàng)建一維NumPy數(shù)組

Numpy提供了很多方式(函數(shù))來創(chuàng)建數(shù)組對象,常用的方式如下:

  • array
  • arange
  • ones / ones_like
  • zeros / zeros_like
  • empty / empty_like
  • full / full_like
  • eye / identity
  • linspace
  • logspace
# 快速定義一維NumPy數(shù)組
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) 
print(b)
print(c) 
print(d) 

# 創(chuàng)建一個長度為5的NumPy數(shù)組事期,但所有元素都為0
my_new_array_0 = np.zeros((5)) 

# 創(chuàng)建一個長度為5的NumPy數(shù)組滥壕,但所有元素都為1
my_new_array_1 = np.ones((5)) 

# 使用的是隨機函數(shù),它為每個元素分配0到1之間的隨機值
my_random_array = np.random.random((5))

print (my_new_array_0)
print (my_new_array_1)
print (my_random_array)
運行結果
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0.         1.57079633 3.14159265 4.71238898 6.28318531]
[0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1.]
[0.92576367 0.91505031 0.21331558 0.28572705 0.69022813]

3.3 創(chuàng)建二維NumPy數(shù)組

# 使用NumPy創(chuàng)建二維數(shù)組
a = np.arange(6).reshape(2,-1)
# print(a.resize((2,3)))  ## 就地修改
print(a)

# Create an array of all zeros
a = np.zeros((2,2))   
         
 # Create an array of all ones
b = np.ones((1,2))             

# Create a constant array
c = np.full((2,2), 999)  
             
# Create a 2x2 identity matrix
d = np.eye(2)                      
                     
print(a)
print(b)
print(c)
print(d)
運行結果
[[0 1 2]
 [3 4 5]]
[[0. 0.]
 [0. 0.]]
[[1. 1.]]
[[999 999]
 [999 999]]
[[1. 0.]
 [0. 1.]]

3.4 數(shù)組屬性

數(shù)組對象具有如下常用屬性:

  • ndim
  • shape
  • dtype
  • size
  • itemsize
  • nbytes
  • astype
  • reshape
  • resize
# 數(shù)組屬性
# Array properties
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, 350]])

print(type(a)) 
print(a.dtype) 
print(a.size) 
print(a.shape) 
#  itemsize屬性是每個項占用的字節(jié)數(shù)兽泣。
# 如果數(shù)據(jù)類型是int 64绎橘,一個int 64中有64位,一個字節(jié)中有8位唠倦,除以64除以8称鳞,你就可以得到它占用了多少字節(jié),
print(a.itemsize)
print(a.ndim)
# nbytes 屬性是數(shù)組中的所有數(shù)據(jù)消耗掉的字節(jié)數(shù)稠鼻。
# 你應該注意到冈止,這并不計算數(shù)組的開銷,因此數(shù)組占用的實際空間將稍微大一點候齿。
print(a.nbytes) 
運行結果
<class 'numpy.ndarray'>
int32
25
(5, 5)
4
2
100

3.5 修改元素

# 修改一個元素
my_array = np.array([1,2,3,4,5,6])
my_array[0] = -1
print (my_array)
# 修改多個元素(也可以切片熙暴,但是我們要改變指定不連續(xù)索引的值,就不能使用切片)
my_array[[0,1,2]] = -1
print (my_array)
運行結果
[-1  2  3  4  5  6]
[-1 -1 -1  4  5  6]

3.6 索引

# 多維數(shù)組可以用 my_array[i][j] 符號來索引毛肋,其中i表示行號怨咪,j表示列號
my_array = np.array([[4, 5], [6, 1]])
print (my_array)
print (my_array[0][1])
# print(my_array[1, 2])

# 提取第二列(索引1)的所有元素
my_array_column_2 = my_array[:, 1] 
print (my_array_column_2)

# 提取第二行(索引1)的所有元素
my_array_column_2 = my_array[1, :] 
print (my_array_column_2)
運行結果
[[4 5]
 [6 1]]
5
[5 1]
[6 1]
# 花式索引:是獲取數(shù)組中我們想要的特定元素的有效方法。
a = np.arange(0, 100, 10)
indices = [1, 5, -1]
b = a[indices]
print(a) 
print(b) 
運行結果
[ 0 10 20 30 40 50 60 70 80 90]
[10 50 90]
import matplotlib.pyplot as plt

a = np.linspace(0, 2 * np.pi, 50)
b = np.sin(a)
plt.plot(a,b)
# mask = b >= 0
# plt.plot(a[mask], b[mask], 'bo')
mask = (b >= 0) & (a <= np.pi)
plt.plot(a[mask], b[mask], 'go')
plt.show()
運行結果
2019081501.png
# 缺省索引
# 不完全索引是從多維數(shù)組的第一個維度獲取索引或切片的一種方便方法
# Incomplete Indexing
a = np.arange(0, 100, 10)
b = a[:5]
c = a[a >= 50]
print(a)
print(b)
print(c) 
運行結果
[ 0 10 20 30 40 50 60 70 80 90]
[ 0 10 20 30 40]
[50 60 70 80 90]
# where() 函數(shù)是另外一個根據(jù)條件返回數(shù)組中的值的有效方法润匙。
# 只需要把條件傳遞給它诗眨,它就會返回一個使得條件為真的元素的索引。

a = np.arange(0, 100, 10)
b = np.where(a < 50) 
c = np.where(a >= 50)[0]
print(b)
print(c) 
運行結果
(array([0, 1, 2, 3, 4], dtype=int64),)
[5 6 7 8 9]
# 整數(shù)數(shù)組索引: 使用切片索引到numpy數(shù)組時孕讳,生成的數(shù)組視圖將始終是原始數(shù)組的子數(shù)組匠楚。 
# 相反,整數(shù)數(shù)組索引允許你使用另一個數(shù)組中的數(shù)據(jù)構造任意數(shù)組厂财。

a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
b = np.array([0, 2, 0, 1])
print(a) 
print(a[np.arange(4), b])  
a[np.arange(4), b] += 10
print(a)  

運行結果
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
[ 1  6  7 11]
[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]

3.7 切片

  • 數(shù)組的切片返回的是原數(shù)組數(shù)據(jù)的視圖(回憶:Python中呢芋簿? python中,切片是淺拷貝).如果需要復制底層的數(shù)組元素璃饱,可以使用數(shù)組對象的copy方法与斤。

  • 注意:視圖是共享底層的數(shù)組元素,但視圖并不是賦值荚恶。

  • python中撩穿,切片是淺拷貝。切片后谒撼,原對象改變不會影響切片后的對象食寡,切片后的對象改變會影響原對象.

  • 數(shù)組的切片,返回的是視圖廓潜,原數(shù)組改變會影響切片后的數(shù)組抵皱,但是切片后的數(shù)組的元素改變也會影響原數(shù)組.

  • 通過數(shù)組對象的copy方法善榛,實現(xiàn)底層數(shù)據(jù)的復制,而不是返回底層數(shù)據(jù)的視圖呻畸。數(shù)組的 copy 方法對復制前后移盆,互不影響.

# 使用多維數(shù)組表示矩陣
# 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]) 

# 多維數(shù)組切片
# MD slicing
print(a[0, 1:4]) 
print(a[1:4, 0]) 
print(a[::2,::2]) 
print(a[:, 1]) 
運行結果
25
[12 13 14]
[16 21 26]
[[11 13 15]
 [21 23 25]
 [31 33 35]]
[12 17 22 27 32]

3.8 加減乘除運算

# numpy數(shù)組的加減乘除是相應位置的運算,且形狀一樣伤为。與矩陣的乘法有區(qū)別
a = np.array([1.0, 2.0]) 
b = np.array([3, 4])
sum = a + b 
difference = a - b 
product = a * b 
quotient = a / b 
print ("Sum = \n", sum )
print ("Difference = \n", difference )
print ("Product = \n", product )
print ("Quotient = \n", quotient )

# 乘法運算符執(zhí)行逐元素乘法而不是矩陣乘法味滞。 要執(zhí)行矩陣乘法,你可以執(zhí)行以下操作
matrix_product = a.dot(b) 
# matrix_product = np.dot(a,b) 
print ("Matrix Product = ", matrix_product)
運行結果
Sum = 
 [4. 6.]
Difference = 
 [-2. -2.]
Product = 
 [3. 8.]
Quotient = 
 [0.33333333 0.5       ]
Matrix Product =  11.0

3.9 比較運算符

# 數(shù)組中使用
a = np.array([[0, 1, 2],
              [3, 4, 5]])
b = np.array([[0, 2, 2],
              [3, 3, 5]])
print(a)
print(b)
# 返回钮呀,布爾類型
print(a < b) 
print(a == b)
print(a != b)
print(a >= b)

運行結果
[[0 1 2]
 [3 4 5]]
[[0 2 2]
 [3 3 5]]
[[False  True False]
 [False False False]]
[[ True False  True]
 [ True False  True]]
[[False  True False]
 [False  True False]]
[[ True False  True]
 [ True  True  True]]

3.10 位運算符

a = np.array([True, True, False, False])
b = np.array([True, False, True, False])

print(a & b)
print(a | b)
print(~a)
print(a & True)
print(a & False)
運行結果
[ True False False False]
[ True  True  True False]
[False False  True  True]
[ True  True False False]
[False False False False]
# 邏輯與

a = np.logical_and([True, False], 
                   [False, False])
print(a)

x = np.arange(5)
y = np.logical_and(x>1, x<4) 
print(y)  # [False, False,  True,  True, False]

# 邏輯或
b = np.logical_or([True, False], 
                  [False, False])  
print(b)  # [ True, False]

x = np.arange(5)
y = np.logical_or(x < 1, x > 3)
print(y)  # [ True, False, False, False,  True]


# 邏輯非
c =  np.logical_not([True, False, 0, 1])
print(c)  # [False,  True,  True, False]

x = np.arange(5)
y = np.logical_not(x<3)
print(y)  # [False, False, False,  True,  True]

# 邏輯異或
d = np.logical_xor([True, True, False, False], 
                   [True, False, True, False])
print(d)  # [False,  True,  True, False], dtype=bool)

x = np.arange(5)
y = np.logical_xor(x < 1, x > 3)
print(y)  # [ True, False, False, False,  True]

運行結果
[False False]
[False False  True  True False]
[ True False]
[ True False False False  True]
[False  True  True False]
[False False False  True  True]
[False  True  True False]
[ True False False False  True]

3.12 數(shù)學運算符

# 數(shù)組數(shù)學函數(shù)
#  sin, cos, tan
a = np.array([0,30,60,90])

# 通過乘 pi/180 轉化為弧度  
print ('正弦值',np.sin(a*np.pi/180))
print ('余弦值',np.cos(a*np.pi/180))
print ('正切值',np.tan(a*np.pi/180))


# arcsin,arccos昨凡,和 arctan 函數(shù)返回給定角度的 sin爽醋,cos 和 tan 的反三角函數(shù)。
# 通過 numpy.degrees() 函數(shù)將弧度轉換為角度便脊。

a1 = np.arcsin(np.sin(a*np.pi/180))
print('反正弦:',a1)
print('轉化為角度:',np.degrees(a1))

運行結果
正弦值 [0.        0.5       0.8660254 1.       ]
余弦值 [1.00000000e+00 8.66025404e-01 5.00000000e-01 6.12323400e-17]
正切值 [0.00000000e+00 5.77350269e-01 1.73205081e+00 1.63312394e+16]
反正弦: [0.         0.52359878 1.04719755 1.57079633]
轉化為角度: [ 0. 30. 60. 90.]
# numpy.around(a,decimals) 
# 函數(shù)返回指定數(shù)字的四舍五入值蚂四。
# * a: 數(shù)組
# * decimals: 舍入的小數(shù)位數(shù)。 默認值為0哪痰。 如果為負遂赠,整數(shù)將四舍五入到小數(shù)點左側的位置
a = np.array([1.0,5.55,  123,  0.567,  25.532])  
print(a)
print(np.around(a, decimals =  1))
print(np.around(a, decimals =  -1))
運行結果
[  1.      5.55  123.      0.567  25.532]
[  1.    5.6 123.    0.6  25.5]
[  0.  10. 120.   0.  30.]
# numpy.floor() 
# 返回數(shù)字的向下取整。
a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])
print (a)
print (np.floor(a))
運行結果
[-1.7  1.5 -0.2  0.6 10. ]
[-2.  1. -1.  0. 10.]
# numpy.ceil() 
# 返回數(shù)字的向上取整晌杰。
print (np.ceil(a))
運行結果
[-1.  2. -0.  1. 10.]
# add()跷睦,subtract(),multiply() 和 divide()肋演。
# 需要注意的是數(shù)組必須具有相同的形狀或符合數(shù)組廣播規(guī)則抑诸。
a = np.arange(9, dtype = np.float_).reshape(3,3)  
b = np.array([2,4,6]) 
print (a)
print (b)

print ('兩個數(shù)組相加:\n')
# print (a+b)
print (np.add(a,b))

print ('兩個數(shù)組相減:\n')
# print (a-b)
print (np.subtract(a,b))

print ('兩個數(shù)組相乘:\n')
# print(a*b)
print (np.multiply(a,b))

print ('兩個數(shù)組相除:\n')
# print(a/b)
print (np.divide(a,b))
# numpy.reciprocal() 函數(shù)返回參數(shù)逐元素的倒數(shù)
a = np.array([0.25,  2,  1,  100])  
print (a)
print (np.reciprocal(a))

# numpy.power() 
# 函數(shù)將第一個輸入數(shù)組中的元素為底數(shù),計算它與第二個輸入數(shù)組相應元素的冪。
a = np.array([10,100,1000])  
b = np.array([1,2,3])  
print (np.power(a,2))
print (np.power(a,b))


# numpy.mod(),numpy.remainder()
# 算輸入數(shù)組中相應元素的相除后的余數(shù)
a = np.array([10,20,30]) 
b = np.array([3,5,7])  

print (np.mod(a,b))
print (np.remainder(a,b))

# numpy.amin() 和 numpy.amax()
# numpy.amin() 用于計算數(shù)組中的元素沿指定軸的最小值爹殊。
# numpy.amax() 用于計算數(shù)組中的元素沿指定軸的最大值蜕乡。
a = np.array([[3,7,5],[8,4,3],[2,4,9]])  
print (a)
print ('axis=None ',np.amin(a))
print ('axis=1 ',np.amin(a,1))
print ('axis=0 ',np.amin(a,0))


# numpy.ptp()
# 函數(shù)計算數(shù)組中元素最大值與最小值的差(最大值 - 最小值)。
a = np.array([[3,7,5],[8,4,3],[2,4,9]])  
print(a)
print('axis=None',np.ptp(a))
print('axis=1',np.ptp(a,axis=1))
print('axis=0',np.ptp(a,axis=0))

# numpy.percentile(a, q, axis)
# 百分位數(shù)是統(tǒng)計中使用的度量梗夸,表示小于這個值的觀察值的百分比层玲。
# a: 輸入數(shù)組
# q: 要計算的百分位數(shù),在 0 ~ 100 之間
# axis: 沿著它計算百分位數(shù)的軸

a = np.array([[10, 7, 4], 
              [3, 2, 1]])

print (a)
# 50% 的分位數(shù)反症,就是 a 里排序之后的中位數(shù)
print (np.percentile(a, 50)) 
 
# axis 為 0辛块,在縱列上求
print (np.percentile(a, 50, axis=0)) 
 
# axis 為 1,在橫行上求
print (np.percentile(a, 50, axis=1)) 
 
# 保持維度不變
print (np.percentile(a, 50, axis=1, keepdims=True))


# numpy.median() 函數(shù)用于計算數(shù)組 a 中元素的中位數(shù)(中值)
a = np.array([[10, 7, 4], 
              [3, 2, 1]])

print (np.median(a))


# numpy.mean() 函數(shù)返回數(shù)組中元素的算術平均值惰帽。 
a = np.array([[1,2,3],[3,4,5],[4,5,6]])  
print(np.mean(a))

# numpy.average() 
# 函數(shù)根據(jù)在另一個數(shù)組中給出的各自的權重計算數(shù)組中元素的加權平均值憨降。
a = np.array([1,2,3,4])  
wts = np.array([4,3,2,1])
print(np.average(a))
print(np.average(a,weights=wts))
# If returned=True, the tuple (`average`, `sum_of_weights`)
print(np.average(a,weights=wts, returned=True))
運行結果
2.5
2.0
(2.0, 10.0)
# numpy.std() 
# 標準差是一組數(shù)據(jù)平均值分散程度的一種度量。
# std = sqrt(mean((x - x.mean())**2))

print(np.std([1,2,3,4])

# np.var()
# 方差(樣本方差)是每個樣本值與全體樣本值的平均數(shù)之差的平方值的平均數(shù)该酗,
# var = mean((x - x.mean())** 2)
print(np.var([1,2,3,4]))

3.13 數(shù)組扁平化

我們可以通過調(diào)用ravel或flatten方法授药,對數(shù)組對象進行扁平化處理士嚎。

  • np.ravel / ravel
  • flatten

二者的區(qū)別在于,ravel返回原數(shù)組的視圖悔叽,而flatten返回原數(shù)組的拷貝莱衩。

x = np.arange(12).reshape(3, -1)
# print(np.ravel(x))
print(x.ravel())
print(x.flatten())
運行結果
[ 0  1  2  3  4  5  6  7  8  9 10 11]
[ 0  1  2  3  4  5  6  7  8  9 10 11]

3.14 連接與拆分函數(shù)

  • np.concatenate 對多個數(shù)組按指定軸的方向進行連接。
  • np.vstack / np.hstack
  • np.split / np.hsplit / np.vsplit
a = np.random.randint(1,9,size=(2,2))
b = np.random.randint(1,9,size=(2,2))
print(a)
print(b)
#按指定軸的方向進行拼接娇澎, 默認axis=0
np.concatenate((a,b))
運行結果
[[7 3]
 [6 1]]
[[3 3]
 [3 6]]
array([[7, 3],
       [6, 1],
       [3, 3],
       [3, 6]])
#對ndarray數(shù)組進行切分笨蚁,axis可以指定方向
#切分時,可以指定一個標量趟庄,表示均等分括细,若不能均等分,則拋錯
a = np.random.randint(0,20,size=(4,5))
print(np.split(a,2))
# #若不想進行均等切分戚啥,可以指定一個列表奋单,來指定切分的索引
np.split(a,[1,3],axis=0)
運行結果
[array([[ 9,  2, 11, 19, 12],
       [ 8,  6, 14, 11, 18]]), array([[11, 14, 17,  5,  1],
       [10, 16,  5, 11, 18]])]
[array([[ 9,  2, 11, 19, 12]]), array([[ 8,  6, 14, 11, 18],
        [11, 14, 17,  5,  1]]), array([[10, 16,  5, 11, 18]])]

3.15 sort方法

  • np.sort 返回新創(chuàng)建的數(shù)組對象,原有的數(shù)組對象不會進行修改
  • 數(shù)組對象的sort 返回的None猫十,原有的對象會改變览濒,(就地修改)
a = np.array([5,-2,4,-3])
print(np.sort(a))
print(a)

a = np.array([5,-2,4,-3])
print(a.sort())
print(a)
運行結果
[-3 -2  4  5]
[ 5 -2  4 -3]
None
[-3 -2  4  5]

4 NumPy 練習

4.1 計算距離

from scipy.spatial.distance import pdist, squareform

# https://docs.scipy.org/doc/scipy/reference
# /generated/scipy.spatial.distance.pdist.html
# 'braycurtis', 'canberra', 'chebyshev', 'cityblock',
# 'correlation', 'cosine', 'dice', 'euclidean', 'hamming',
# 'jaccard', 'jensenshannon', 'kulsinski', 'mahalanobis', 'matching',
# 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean',
# 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'

x = np.array([[0, 1,2,3], 
              [1, 0,2,3], 
              [2, 0,2,3]])
a = pdist(x, 'euclidean')
b = squareform(pdist(x, 'euclidean'))
print(a)
print(b)
運行結果
[1.41421356 2.23606798 1.        ]
[[0.         1.41421356 2.23606798]
 [1.41421356 0.         1.        ]
 [2.23606798 1.         0.        ]]

4.2 所有奇數(shù)替換為-1

# 將arr中的所有奇數(shù)替換為-1。
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[arr % 2 == 1] = -1
print(arr)

# 將arr中的所有奇數(shù)替換為-1拖云,而不改變arr贷笛。
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
out = np.where(arr % 2 == 1, -1, arr)
print(arr)
print(out)
運行結果
[ 0 -1  2 -1  4 -1  6 -1  8 -1]
[0 1 2 3 4 5 6 7 8 9]
[ 0 -1  2 -1  4 -1  6 -1  8 -1]

4.3 生成自定義序列

# 不使用硬編碼,生成numpy中的自定義序列
a = np.array([1,2,3])
# np.r_[np.repeat(a, 3), np.tile(a, 3)]
np.concatenate([np.repeat(a, 3), np.tile(a, 3)])
運行結果
array([1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3])

4.4 獲取數(shù)組之間的公共項

# 獲取數(shù)組a和數(shù)組b之間的公共項。
a = np.array([1,2,3,2,3,4,3,4,5,6]).reshape(2,-1)
b = np.array([7,2,10,2,7,4,9,4,9,8]).reshape(2,-1)
np.intersect1d(a,b)
運行結果
array([2, 4])

4.5 從數(shù)組中刪除另一個數(shù)組中的所有項

# 從數(shù)組a中刪除數(shù)組b中的所有項宙项。
a = np.array([1,2,3,4,5])
b = np.array([5,6,7,8,9])

np.setdiff1d(a,b)
運行結果
array([1, 2, 3, 4])

4.6 獲取數(shù)組中元素匹配的位置

# 獲取a和b元素匹配的位置乏苦。
a = np.array([1,2,3,2,3,4,3,4,5,6])
b = np.array([7,2,10,2,7,4,9,4,9,8])
np.where(a == b)
運行結果
(array([1, 3, 5, 7], dtype=int64),)

4.7 數(shù)組中提取給定范圍的元素

# 從numpy數(shù)組中提取給定范圍內(nèi)的所有數(shù)字
# 獲取5到10之間的所有元素 [6, 9, 10]
a = np.array([2, 6, 1, 9, 10, 3, 27])
# Method 1
index = np.where((a >= 5) & (a <= 10))
a[index]

# Method 2:
index = np.where(np.logical_and(a>=5, a<=10))
a[index]

# Method 3: 
a[(a >= 5) & (a <= 10)]
運行結果
array([ 6,  9, 10])
numpy.vectorize
  • numpy.vectorize(pyfunc, otypes=None, doc=None, excluded=None, cache=False, signature=None)

  • Parameters:

  • pyfunc : python函數(shù)或方法

  • otypes : 輸出數(shù)據(jù)類型。必須將其指定為一個typecode字符串或一個數(shù)據(jù)類型說明符列表杉允。每個輸出應該有一個數(shù)據(jù)類型說明符邑贴。

  • doc : 函數(shù)的docstring。如果為None叔磷,則docstring將是 pyfunc.doc拢驾。

  • excluded : 表示函數(shù)不會向量化的位置或關鍵字參數(shù)的字符串或整數(shù)集。這些將直接傳遞給未經(jīng)修改的pyfunc

  • cache :如果為True改基,則緩存第一個函數(shù)調(diào)用繁疤,該函數(shù)調(diào)用確定未提供otype的輸出數(shù)。

  • signature : 廣義通用函數(shù)簽名秕狰,例如稠腊,(m,n),(n)->(m)用于矢量化矩陣 - 向量乘法。如果提供的話鸣哀,pyfunc將調(diào)用(并期望返回)具有由相應核心維度的大小給出的形狀的數(shù)組架忌。默認情況下,pyfunc假定將標量作為輸入和輸出我衬。

  • Returns:

  • vectorized :向量化的數(shù)組

4.8 多個數(shù)組對應位置的最大值

# 轉換適用于兩個標量的函數(shù)maxx叹放,以處理兩個數(shù)組饰恕。
a = np.array([5, 7, 9, 8, 6, 4, 5])
b = np.array([6, 3, 4, 8, 9, 7, 1])

# Method 1
def maxx(x, y):
    """Get the maximum of two items"""
    if x >= y:
        return x
    else:
        return y
pair_max = np.vectorize(maxx, otypes=[float])
pair_max(a, b)

# Method 2
c = np.concatenate((a,b)).reshape(2,-1)
np.max(c,axis=0)
運行結果
array([6, 7, 9, 8, 9, 7, 5])

4.9 交換行,列

# 在數(shù)組arr中交換列1和2。
arr = np.arange(9).reshape(3,3)
print(arr)
print(arr[:, [1,0,2]])

# 交換數(shù)組arr中的第1和第2行:
arr[[1,0,2], :]
運行結果
[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[1 0 2]
 [4 3 5]
 [7 6 8]]
array([[3, 4, 5],
       [0, 1, 2],
       [6, 7, 8]])

4.10 反轉行,列

# 反轉二維數(shù)組arr的行井仰。
print(arr[::-1,:])
# 反轉二維數(shù)組arr的列埋嵌。
print(arr[:,::-1])
運行結果
[[6 7 8]
 [3 4 5]
 [0 1 2]]
[[2 1 0]
 [5 4 3]
 [8 7 6]]
random模塊提供生成隨機數(shù)的功能(偽隨機數(shù))。常用功能如下:
  • random():返回一個0 ~ 1之間的浮點數(shù)俱恶,包括0雹嗦,不包括1。
  • randint(a, b):返回一個a ~ b之間的整數(shù)合是。包括a與b了罪。
  • randrange(start, stop[, step]):參數(shù)與range函數(shù)的意義相同,相當于從相同參數(shù)的range函數(shù)可能產(chǎn)生的值中聪全,隨便選擇一個捶惜。
  • uniform(a, b):返回a與b之間的浮點數(shù),包括端點荔烧。
  • choice(seq):從seq(可迭代對象)中隨機選擇一個元素。如果序列為空汽久,則產(chǎn)生錯誤鹤竭。該抽樣是放回抽樣。
  • choices(iterable, weights=None, *, cum_weights=None, k=1):從iterable(可迭代對象)中選擇k個元素景醇,放入一個新列表(不會改變原有的列表)并返回臀稚。如果提供了weights(權重)或cum_weights(累積權重),則元素的選擇概率會根據(jù)權重(累積權重)決定三痰。權重與累積權重不能同時指定吧寺,因為權重內(nèi)部會轉換成累積權重,這樣會造成不一致散劫。如果沒有指定權重與累積權重稚机,則各個元素的選擇概率相同。
  • sample(iterable, k):從iterable(可迭代對象)中選擇k個元素获搏,返回元素組成的新列表(不會改變原有的列表)赖条。該抽樣是不放回抽樣。
  • shuffle(x[, random]):對x(序列)進行洗牌常熙。random是一個可選的生成隨機數(shù)的函數(shù)纬乍,函數(shù)的返回值為[0, 1),默認使用random模塊的random函數(shù)裸卫。(就地修改)
np.random模塊提供生成隨機數(shù)的功能(偽隨機數(shù))
  • np.random.rand
  • np.random.random
  • np.random.randn
  • np.random.normal
  • np.random.randint
  • np.random.seed
  • np.random.shuffle
  • np.random.uniform

4.11 創(chuàng)建指定區(qū)間的隨機數(shù)

# 創(chuàng)建一個形狀為5x3的二維數(shù)組仿贬,以包含5到10之間的隨機十進制數(shù)。
arr = np.arange(9).reshape(3,3)

# Solution Method 1:
rand_arr = np.random.randint(low=5, high=10, size=(5,3)) + np.random.random((5,3))
# print(rand_arr)

# Solution Method 2:
rand_arr = np.random.uniform(5,10, size=(5,3))
print(rand_arr)
運行結果
[[7.00895215 5.34171314 9.02545605]
 [8.77938223 9.15814271 5.46713387]
 [8.35351152 7.02282564 9.59648514]
 [6.10883598 8.04277479 8.60606051]
 [9.54183886 5.38980032 8.69235166]]

4.12 保留指定小數(shù)點位數(shù)

# 只打印或顯示numpy數(shù)組rand_arr的小數(shù)點后3位墓贿。
rand_arr = np.random.random([5,3])

# Limit to 3 decimal places
np.set_printoptions(precision=3)
rand_arr
運行結果
array([[0.18 , 0.728, 0.831],
       [0.146, 0.64 , 0.984],
       [0.08 , 0.556, 0.083],
       [0.156, 0.224, 0.255],
       [0.964, 0.317, 0.955]])

4.13 科學記數(shù)法

# 通過e式科學記數(shù)法來打印rand_arr(如1e10)
np.set_printoptions(suppress=False)

# Create the random array
np.random.seed(100)
rand_arr = np.random.random([3,3])/1e3
print(rand_arr)

np.set_printoptions(suppress=True, precision=6)  # precision is optional
rand_arr

運行結果
[[5.434e-04 2.784e-04 4.245e-04]
 [8.448e-04 4.719e-06 1.216e-04]
 [6.707e-04 8.259e-04 1.367e-04]]
array([[0.000543, 0.000278, 0.000425],
       [0.000845, 0.000005, 0.000122],
       [0.000671, 0.000826, 0.000137]])

4.14 指定打印的元素個數(shù)

# 如何限制numpy數(shù)組輸出中打印的項目數(shù)茧泪?
np.set_printoptions(threshold=6)
a = np.arange(15)
print(a)

# 如何打印完整的numpy數(shù)組而不截斷
np.set_printoptions(threshold=1000)
a = np.arange(15)
print(a)
運行結果
[ 0  1  2 ... 12 13 14]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

4.15 規(guī)范化數(shù)組

 如何規(guī)范化數(shù)組蜓氨,使數(shù)組的值正好介于0和1之間?
# Input
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
sepallength = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0])[0:50]

# Solution
Smax, Smin = sepallength.max(), sepallength.min()
S = (sepallength - Smin)/(Smax - Smin)
# or 
S = (sepallength - Smin)/sepallength.ptp()  
print(S)

4.16 數(shù)組的百分位數(shù)

# 如何找到numpy數(shù)組的百分位數(shù)调炬?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
sepallength = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0])

# Solution
np.percentile(sepallength, q=[5, 95])
運行結果
array([4.6  , 7.255])
numpy.where() 有兩種用法:
    1. np.where(condition, x, y)
      • 滿足條件(condition)语盈,輸出x,不滿足輸出y缰泡。
    1. np.where(condition)
      • 只有條件 (condition)刀荒,沒有x和y,則輸出滿足條件 (即非0) 元素的坐標 (等價于numpy.nonzero)棘钞。這里的坐標以tuple的形式給出缠借,通常原數(shù)組有多少維,輸出的tuple中就包含幾個數(shù)組宜猜,分別對應符合條件元素的各維坐標泼返。

4.17 隨機位置插入值

# 如何在數(shù)組中的隨機位置插入值?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='object')

# Method 1
i, j = np.where(iris_2d)
# i, j contain the row numbers and column numbers of 600 elements of iris_x
np.random.seed(100)
iris_2d[np.random.choice((i), 20), np.random.choice((j), 20)] = np.nan


# Method 2
np.random.seed(100)
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan
# Print first 10 rows
print(iris_2d[:10])
運行結果
[[b'5.1' b'3.5' b'1.4' b'0.2' b'Iris-setosa']
 [b'4.9' b'3.0' b'1.4' b'0.2' b'Iris-setosa']
 [b'4.7' b'3.2' b'1.3' b'0.2' b'Iris-setosa']
 [b'4.6' b'3.1' b'1.5' b'0.2' b'Iris-setosa']
 [b'5.0' b'3.6' b'1.4' b'0.2' b'Iris-setosa']
 [b'5.4' b'3.9' b'1.7' b'0.4' b'Iris-setosa']
 [b'4.6' b'3.4' b'1.4' b'0.3' b'Iris-setosa']
 [b'5.0' b'3.4' b'1.5' b'0.2' b'Iris-setosa']
 [b'4.4' nan b'1.4' b'0.2' b'Iris-setosa']
 [b'4.9' b'3.1' b'1.5' b'0.1' b'Iris-setosa']]

4.18 查詢?nèi)笔е档奈恢?/h2>
# 如何在numpy數(shù)組中找到缺失值的位置姨拥?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan

# Solution
print("Number of missing values: \n", np.isnan(iris_2d[:, 0]).sum())
print("Position of missing values: \n", np.where(np.isnan(iris_2d[:, 0])))

運行結果
Number of missing values: 
 5
Position of missing values: 
 (array([ 38,  80, 106, 113, 121], dtype=int64),)

4.19 篩選數(shù)據(jù)

# 如何根據(jù)兩個或多個條件過濾numpy數(shù)組绅喉?
# 過濾具有petallength(第3列)> 1.5 和 sepallength(第1列)< 5.0 的數(shù)據(jù)
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])

# Solution
condition = (iris_2d[:, 2] > 1.5) & (iris_2d[:, 0] < 5.0)
iris_2d[condition]
運行結果
array([[4.8, 3.4, 1.6, 0.2],
       [4.8, 3.4, 1.9, 0.2],
       [4.7, 3.2, 1.6, 0.2],
       [4.8, 3.1, 1.6, 0.2],
       [4.9, 2.4, 3.3, 1. ],
       [4.9, 2.5, 4.5, 1.7]])

4.20 刪除包含缺失值的行

# 如何從numpy數(shù)組中刪除包含缺失值的行?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan

# Solution
# No direct numpy function for this.

# Method 1:
any_nan_in_row = np.array([~np.any(np.isnan(row)) for row in iris_2d])
iris_2d[any_nan_in_row][:5]

# Method 2: (By Rong)
iris_2d[np.sum(np.isnan(iris_2d), axis = 1) == 0][:5]
運行結果
array([[4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       [4.6, 3.4, 1.4, 0.3]])

4.21 數(shù)組相關性

# 如何找到numpy數(shù)組的兩列之間的相關性叫乌?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])

# Solution 1
print(np.corrcoef(iris[:, 0], iris[:, 2])[0, 1])

# Solution 2
from scipy.stats.stats import pearsonr  
corr, p_value = pearsonr(iris[:, 0], iris[:, 2])
print(corr)
運行結果
0.8717541573048718
0.8717541573048713

4.22 查找數(shù)組是否具有任何空值

# 如何查找給定數(shù)組是否具有任何空值柴罐?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])

np.isnan(iris_2d).any()
運行結果
False

4.23 用指定值替換所有缺失值

# 如何在numpy數(shù)組中用0替換所有缺失值?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='float', usecols=[0,1,2,3])
iris_2d[np.random.randint(150, size=20), np.random.randint(4, size=20)] = np.nan


iris_2d[np.isnan(iris_2d)] = 0
iris_2d[:4]
運行結果
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2]])

4.24 查找唯一值的計數(shù)

# 如何在numpy數(shù)組中查找唯一值的計數(shù)憨奸?

# Import iris keeping the text column intact
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
names = ('sepallength', 'sepalwidth', 'petallength', 'petalwidth', 'species')

# Solution
# Extract the species column as an array
species = np.array([row.tolist()[4] for row in iris])

# Get the unique values and the counts
np.unique(species, return_counts=True)
運行結果
(array([b'Iris-setosa', b'Iris-versicolor', b'Iris-virginica'],
       dtype='|S15'), array([50, 50, 50], dtype=int64))

4.25 數(shù)字轉換為文本數(shù)組

# 如何將數(shù)字轉換為分類(文本)數(shù)組革屠?

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
names = ('sepallength', 'sepalwidth', 'petallength', 'petalwidth', 'species')

# Bin petallength 
petal_length_bin = np.digitize(iris[:, 2].astype('float'), [0, 3, 5, 10])

# Map it to respective category
label_map = {1: 'small', 2: 'medium', 3: 'large', 4: np.nan}
petal_length_cat = [label_map[x] for x in petal_length_bin]

# View
petal_length_cat[:4]

運行結果
['small', 'small', 'small', 'small']

4.26 利用現(xiàn)有列創(chuàng)建新列

# 如何從numpy數(shù)組的現(xiàn)有列創(chuàng)建新列?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris_2d = np.genfromtxt(url, delimiter=',', dtype='object')

# Solution
# Compute volume
sepallength = iris_2d[:, 0].astype('float')
petallength = iris_2d[:, 2].astype('float')
volume = (np.pi * petallength * (sepallength**2))/3
print(volume.shape)

# Introduce new dimension to match iris_2d's
volume = volume[:, np.newaxis]
print(volume.shape)

# Add the new column
out = np.hstack([iris_2d, volume])

# View
out[:4]
運行結果
(150,)
(150, 1)
array([[b'5.1', b'3.5', b'1.4', b'0.2', b'Iris-setosa',
        38.13265162927291],
       [b'4.9', b'3.0', b'1.4', b'0.2', b'Iris-setosa',
        35.200498485922445],
       [b'4.7', b'3.2', b'1.3', b'0.2', b'Iris-setosa', 30.0723720777127],
       [b'4.6', b'3.1', b'1.5', b'0.2', b'Iris-setosa',
        33.238050274980004]], dtype=object)
使用np.c_和np.r_實現(xiàn)數(shù)組轉換成矩陣
  • np.r_是按列連接多個矩陣排宰,就是把多矩陣上下相加似芝,要求列數(shù)相等。
    • eg:(3,5),(2,5) --> (5,5)
  • np.c_是按行連接多個矩陣板甘,就是把多矩陣左右相加党瓮,要求行數(shù)相等。
    • eg:(5,3),(5,2) --> (5,5)

4.27 查找數(shù)組在另一個數(shù)組中的位置

# 二分法查找b在a中的位置盐类,返回位置索引值
np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])

運行結果
array([0, 5, 1, 2], dtype=int64)

4.28 概率抽樣數(shù)據(jù)

#  如何在numpy中進行概率抽樣麻诀?
# 隨機抽鳶尾屬植物的種類,使得剛毛的數(shù)量是云芝和維吉尼亞的兩倍

# Import iris keeping the text column intact
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')

# Solution
# Get the species column
species = iris[:, 4]

# Approach 1: Generate Probablistically
np.random.seed(100)
a = np.array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'])
species_out = np.random.choice(a, 150, p=[0.5, 0.25, 0.25])

# Approach 2: Probablistic Sampling (preferred)
np.random.seed(100)
probs = np.r_[np.linspace(0, 0.500, num=50), np.linspace(0.501, .750, num=50), np.linspace(.751, 1.0, num=50)]
index = np.searchsorted(probs, np.random.random(150))
species_out = species[index]
print(np.unique(species_out, return_counts=True))
運行結果
(array([b'Iris-setosa', b'Iris-versicolor', b'Iris-virginica'],
      dtype=object), array([77, 37, 36], dtype=int64))

4.29 按另一個數(shù)組分組時獲取數(shù)組的第二大值

# 如何在按另一個數(shù)組分組時獲取數(shù)組的第二大值傲醉?
# 問題:第二長的物種setosa的價值是多少
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')

# Solution
# Get the species and petal length columns
petal_len_setosa = iris[iris[:, 4] == b'Iris-setosa', [2]].astype('float')

# Get the second last value
np.unique(np.sort(petal_len_setosa))[-2]

4.30 對數(shù)組進行排序

print(iris[iris[:,0].argsort()][:20])

4.31 數(shù)組中眾數(shù)

#  如何在numpy數(shù)組中找到眾數(shù)蝇闭?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')

# Solution:
vals, counts = np.unique(iris[:, 0], return_counts=True)
print(vals[np.argmax(counts)])

from scipy import stats
print(stats.mode(iris)[0][0])

#bincount():統(tǒng)計非負整數(shù)的個數(shù),不能統(tǒng)計浮點數(shù)
counts = np.bincount(np.array([1,2,3,5,6,6,6,4,7,8]))
#返回眾數(shù)
print(np.argmax(counts))
運行結果
b'5.0'
[b'5.0' b'3.0' b'1.5' b'0.2' b'Iris-setosa']
6

4.32 查找數(shù)組中大于指定值的位置及值


x = np.array([[3, 0, 0], 
              [0, 4, 0], 
              [5, 6, 0]])


print(np.nonzero(x>3))
print(np.transpose(np.nonzero(x>3)))
print(x[np.nonzero(x>3)])
運行結果
(array([1, 2, 2], dtype=int64), array([1, 0, 1], dtype=int64))
[[1 1]
 [2 0]
 [2 1]]
[4 5 6]

4.33 首次出現(xiàn)的值大于給定值的位置

# 如何找到第一次出現(xiàn)的值大于給定值的位置硬毕?
# 查找第一次出現(xiàn)的值大于1.0的位置呻引。
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')

# method 1:
print(np.transpose(np.nonzero(iris[:, 3].astype(float)>1.0))[0])

# method 2:
np.argwhere(iris[:, 3].astype(float) > 1.0)[0]

4.34 大于給定值的所有值替換為給定值

# 如何將大于給定值的所有值替換為給定的截止值?
# 問題:從數(shù)組a中吐咳,替換所有大于30的值更改為30 和 小于10的值更改為10逻悠。
np.set_printoptions(precision=2)
np.random.seed(100)
a = np.random.uniform(1,50, 20)
print(a)

# Solution 1: Using np.clip
print(np.clip(a, a_min=10, a_max=30))

# Solution 2: Using np.where
print(np.where(a<10, 10, np.where(a>30,30,a)))
運行結果
[27.63 14.64 21.8  42.39  1.23  6.96 33.87 41.47  7.7  29.18 44.67 11.25
 10.08  6.31 11.77 48.95 40.77  9.43 41.   14.43]
[27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
 10.08 10.   11.77 30.   30.   10.   30.   14.43]
[27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
 10.08 10.   11.77 30.   30.   10.   30.   14.43]
np.argpartition()
  • numpy.argpartition(a, kth, axis=-1, kind='introselect', order=None)
  • 在快排算法中元践,有一個典型的操作:partition。這個操作指:根據(jù)一個數(shù)值x童谒,把數(shù)組中的元素劃分成兩半单旁,使得index前面的元素都不大于x,index后面的元素都不小于x饥伊。
  • numpy中的argpartition()函數(shù)就是起的這個作用象浑。對于傳入的數(shù)組a,先用O(n)復雜度求出第k大的數(shù)字琅豆,然后利用這個第k大的數(shù)字將數(shù)組a劃分成兩半愉豺。
  • 此函數(shù)不對原數(shù)組進行操作,它只返回分區(qū)之后的下標茫因。一般numpy中以arg開頭的函數(shù)都是返回下標而不改變原數(shù)組蚪拦。

4.35 數(shù)組5個最大值的位置

# 問題:獲取給定數(shù)組a中前5個最大值的位置。
np.random.seed(100)
a = np.random.uniform(1,50, 20)


# Method 1:
print(a.argsort()[::-1][:5])

# Method 2:
print(np.argpartition(-a,kth=5)[:5])

4.36 按行計算唯一值的計數(shù)

# 問題:按行計算唯一值的計數(shù)冻押。
# 輸出包含10列驰贷,表示從1到10的數(shù)字。這些值是各行中數(shù)字的計數(shù)洛巢。
np.random.seed(100)
arr = np.random.randint(1,11,size=(6, 10))
print(arr)

# Solution 1:
def counts_of_all_values_rowwise(arr2d):
    # Unique values and its counts row wise
    num_counts_array = [np.unique(row, return_counts=True) for row in arr2d]

    # Counts of all values row wise
    return([[int(b[a==i]) if i in a else 0 for i in np.unique(arr2d)] for a, b in num_counts_array])

# [ 1  2  3  4  5  6  7  8  9 10]
print(counts_of_all_values_rowwise(arr))
運行結果
[[ 9  9  4  8  8  1  5  3  6  3]
 [ 3  3  2  1  9  5  1 10  7  3]
 [ 5  2  6  4  5  5  4  8  2  2]
 [ 8  8  1  3 10 10  4  3  6  9]
 [ 2  1  8  7  3  1  9  3  6  2]
 [ 9  2  6  5  3  9  4  6  1 10]]
[[1, 0, 2, 1, 1, 1, 0, 2, 2, 0], 
[2, 1, 3, 0, 1, 0, 1, 0, 1, 1],
 [0, 3, 0, 2, 3, 1, 0, 1, 0, 0], 
[1, 0, 2, 1, 0, 1, 0, 2, 1, 2], 
[2, 2, 2, 0, 0, 1, 1, 1, 1, 0], 
[1, 1, 1, 1, 1, 2, 0, 0, 2, 1]]

4.37 扁平化數(shù)組

# 如何將數(shù)組轉換為平面一維數(shù)組饱苟?
arr_2d = np.arange(20).reshape(4,-1)
print(arr_2d)

# Solution 1
arr_1d = np.array([a for i in arr_2d for a in i])
print(arr_1d)

# Solution 2:
arr_1d = np.concatenate(arr_2d)
print(arr_1d)

# flatten()分配了新的內(nèi)存,但ravel()返回的是一個數(shù)組的視圖
print(arr_2d.flatten())
print(arr_2d.ravel())

4.38 單熱編碼

# 如何在numpy中為數(shù)組生成單熱編碼?
np.random.seed(101) 
arr = np.random.randint(1,4, size=6)
print(arr)


# Solution:
def one_hot_encodings(arr):
    uniqs = np.unique(arr)
    out = np.zeros((arr.shape[0], uniqs.shape[0]))
    for i, k in enumerate(arr):
        out[i, k-1] = 1
    return out

print(one_hot_encodings(arr))


# Method 2:
print((arr[:, None] == np.unique(arr)).view(np.int8))
運行結果
[2 3 2 2 2 1]
[[0. 1. 0.]
 [0. 0. 1.]
 [0. 1. 0.]
 [0. 1. 0.]
 [0. 1. 0.]
 [1. 0. 0.]]
[[0 1 0]
 [0 0 1]
 [0 1 0]
 [0 1 0]
 [0 1 0]
 [1 0 0]]

4.39 按分類變量分組

# 如何創(chuàng)建按分類變量分組的行號狼渊?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
species = np.genfromtxt(url, delimiter=',', dtype='str', usecols=4)
np.random.seed(100)
species_small = np.sort(np.random.choice(species, size=20))
print(species_small)

print([i for val in np.unique(species_small) for i,grp in enumerate(species_small[species_small==val])])

運行結果
['Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica']
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5]

4.40 分類變量創(chuàng)建組ID

# 如何根據(jù)給定的分類變量創(chuàng)建組ID?
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
species = np.genfromtxt(url, delimiter=',', dtype='str', usecols=4)
np.random.seed(100)
species_small = np.sort(np.random.choice(species, size=20))
print(species_small)



# Solution: For Loop version
output = []
uniqs = np.unique(species_small)

for val in uniqs:  # uniq values in group
    for s in species_small[species_small==val]:  # each element in group
        groupid = np.argwhere(uniqs == s).tolist()[0][0]  # groupid
        output.append(groupid)

print(output)

output = [np.argwhere(np.unique(species_small) == s).tolist()[0][0] for val in np.unique(species_small) for s in species_small[species_small==val]]
print(output)
運行結果
['Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica']
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]
argsort()函數(shù)是用來返回數(shù)組值從小到大索引值的嚣镜。
  • a = [6,4,5]
  • 矩陣a從小到大排序仗谆,記排序后的矩陣為 b = [4,5,6]
  • a.argsort() = [1,2,0]
  • 矩陣a和b的關系:
    • b的第一個元素“4”對應的是a矩陣的第2個元素岛都,也就是a[1]
    • b的第二個元素“5”對應的是a矩陣的第3個元素,也就是a[2]
    • b的第三個元素“6”對應的是a矩陣的第1個元素米苹,也就是a[0]

4.41 數(shù)組中的元素排名

#  如何使用numpy對數(shù)組中的項進行排名?
np.random.seed(10)
a = np.random.randint(20, size=10)
print('Array: ', a)

# Solution
print(a.argsort().argsort())
print('Array: ', a)
運行結果
Array:  [ 9  4 15  0 17 16 17  8  9  0]
[4 2 6 0 8 7 9 3 5 1]
Array:  [ 9  4 15  0 17 16 17  8  9  0]

4.42 多維數(shù)組中的每一項進行排名

# 如何使用numpy對多維數(shù)組中的每一項進行排名砰琢?
np.random.seed(10)
a = np.random.randint(20, size=[2,5])
print(a)

# Solution
print(a.ravel().argsort().argsort().reshape(a.shape))
運行結果
[[ 9  4 15  0 17]
 [16 17  8  9  0]]
[[4 2 6 0 8]
 [7 9 3 5 1]]

4.43 數(shù)組的每一行中找到最大值

# 如何在二維numpy數(shù)組的每一行中找到最大值蘸嘶?
np.random.seed(100)
a = np.random.randint(1,10, [5,3])
print(a)

# Solution 1
print(np.amax(a, axis=1))

# Solution 2
print(np.apply_along_axis(np.max, arr=a, axis=1))
運行結果
[[9 9 4]
 [8 8 1]
 [5 3 6]
 [3 3 3]
 [2 1 9]]
[9 8 6 3 9]
[9 8 6 3 9]

4.44 數(shù)組的每一行中找到最小值

# 如何計算二維numpy數(shù)組每行的最小值?

np.random.seed(100)
a = np.random.randint(1,10, [5,3])
print(a)

# Solution
print(np.apply_along_axis(lambda x: np.min(x), arr=a, axis=1))
運行結果
[[9 9 4]
 [8 8 1]
 [5 3 6]
 [3 3 3]
 [2 1 9]]
[4 1 3 3 1]

4.45 標記重復的元素

# 問題:在給定的numpy數(shù)組中找到重復的條目(第二次出現(xiàn)以后)陪汽,并將它們標記為True训唱。第一次出現(xiàn)應該是False的。
np.random.seed(100)
a = np.random.randint(0, 5, 10)
print(a)


# Find the index positions of unique elements
unique_positions = np.unique(a, return_index=True)[1]

# Mark those positions as False
out[unique_positions] = False

print(out)

4.46 按分類列分組的數(shù)值列的平均值

# 問題:在二維數(shù)字數(shù)組中查找按分類列分組的數(shù)值列的平均值

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
iris = np.genfromtxt(url, delimiter=',', dtype='object')
names = ('sepallength', 'sepalwidth', 'petallength', 'petalwidth', 'species')


# Solution
# No direct way to implement this. Just a version of a workaround.
numeric_column = iris[:, 1].astype('float')  # sepalwidth
grouping_column = iris[:, 4]  # species

# List comprehension version
[[group_val, numeric_column[grouping_column==group_val].mean()] for group_val in np.unique(grouping_column)]

# For Loop version
output = []
for group_val in np.unique(grouping_column):
    output.append([group_val, numeric_column[grouping_column==group_val].mean()])

output
運行結果
[[b'Iris-setosa', 3.418],
 [b'Iris-versicolor', 2.7700000000000005],
 [b'Iris-virginica', 2.974]]

4.47 PIL圖像轉換為numpy數(shù)組

# 如何將PIL圖像轉換為numpy數(shù)組挚冤?
from io import BytesIO
from PIL import Image
import PIL, requests

# Import image from URL
URL = 'https://upload.wikimedia.org/wikipedia/commons/8/8b/Denali_Mt_McKinley.jpg'
response = requests.get(URL)

# Read it as Image
I = Image.open(BytesIO(response.content))

# Optionally resize
I = I.resize([150,150])

# Convert to numpy array
arr = np.asarray(I)

# Optionaly Convert it back to an image and show
im = PIL.Image.fromarray(np.uint8(arr))
Image.Image.show(im)

4.48 組中刪除所有NaN值

# 問題:從一維numpy數(shù)組中刪除所有NaN值
a = np.array([1,2,3,np.nan,5,6,7,np.nan])
print(a)
print(a[~np.isnan(a)])

4.49 范數(shù)

# np.linalg.norm(求范數(shù))
# linalg=linear(線性)+algebra(代數(shù))况增,norm則表示范數(shù)。
import numpy as np
x = np.array([[0, 3, 4],
              [1, 6, 4]])
#默認參數(shù)ord=None训挡,axis=None澳骤,keepdims=False
print ("默認參數(shù)(矩陣整體元素平方和開根號歧强,不保留矩陣二維特性):\n",np.linalg.norm(x))
print ("矩陣整體元素平方和開根號,保留矩陣二維特性:\n",np.linalg.norm(x,keepdims=True))
 
print ("矩陣每個行向量求向量的2范數(shù):\n",np.linalg.norm(x,axis=1,keepdims=True))
print ("矩陣每個列向量求向量的2范數(shù):\n",np.linalg.norm(x,axis=0,keepdims=True))
 
print ("矩陣1范數(shù):\n",np.linalg.norm(x,ord=1,keepdims=True))
print ("矩陣2范數(shù):\n",np.linalg.norm(x,ord=2,keepdims=True))
print ("矩陣∞范數(shù):\n",np.linalg.norm(x,ord=np.inf,keepdims=True))
print ("矩陣每個行向量求向量的1范數(shù):\n",np.linalg.norm(x,ord=1,axis=1,keepdims=True))
運行結果
默認參數(shù)(矩陣整體元素平方和開根號为肮,不保留矩陣二維特性):
 8.831760866327848
矩陣整體元素平方和開根號摊册,保留矩陣二維特性:
 [[8.83]]
矩陣每個行向量求向量的2范數(shù):
 [[5.  ]
 [7.28]]
矩陣每個列向量求向量的2范數(shù):
 [[1.   6.71 5.66]]
矩陣1范數(shù):
 [[9.]]
矩陣2范數(shù):
 [[8.7]]
矩陣∞范數(shù):
 [[11.]]
矩陣每個行向量求向量的1范數(shù):
 [[ 7.]
 [11.]]

4.50 歐氏距離

# 問題:計算兩個數(shù)組a和數(shù)組b之間的歐氏距離。
a = np.array([1,2,3,4,5])
b = np.array([4,5,6,7,8])

# Solution
dist = np.linalg.norm(a-b)
print(dist)

dist = np.sqrt(((a-b)**2).sum())
print(dist)

4.51 數(shù)組中的所有峰值

# 問題:找到一個一維數(shù)字數(shù)組a中的所有峰值颊艳。峰頂是兩邊被較小數(shù)值包圍的點茅特。
a = np.array([1, 3, 7, 1, 2, 6, 0, 1, 1])
doublediff = np.diff(np.sign(np.diff(a)))
peak_locations = np.where(doublediff == -2)[0] + 1
peak_locations
運行結果
array([2, 5], dtype=int64)

4.52 第n次重復元素的索引

# 如何查找數(shù)組中項的第n次重復索引?
x = np.array([1, 2, 1, 1, 3, 4, 3, 1, 1, 2, 1, 1, 2])
n = 5

# Solution 1: List comprehension
a = [i for i, v in enumerate(x) if v == 1][n-1]
print(a)

# Solution 2: Numpy version
b = np.where(x == 1)[0][n-1]
print(a)

4.53 datetime64轉換為datetime

# 將numpy的datetime64對象轉換為datetime的datetime對象

import pandas as pd
dt64 = np.datetime64('2018-02-25 22:10:10')

# Solution
from datetime import datetime
print(type(dt64.tolist()))

print(type(dt64.astype(datetime)))

print(dt64.astype(datetime))
print(pd.to_datetime(dt64))
運行結果
<class 'datetime.datetime'>
<class 'datetime.datetime'>
2018-02-25 22:10:10
2018-02-25 22:10:10

4.54 計算窗口大小為3的移動平均值

# 問題:對于給定的一維數(shù)組籽暇,計算窗口大小為3的移動平均值温治。
def moving_average(a, n=3) :
    ret = np.cumsum(a, dtype=float)
    ret[n:] = ret[n:] - ret[:-n]
    return ret[n-1:] / n

np.random.seed(100)
Z = np.random.randint(10, size=10)
print('array: ', Z)

# Method 1
print(moving_average(Z, n=3).round(8))

# Method 2:  
# np.ones(3)/3 gives equal weights. Use np.ones(4)/4 for window size 4.
print(np.convolve(Z, np.ones(3)/3, mode='valid'))
運行結果
array:  [8 8 3 7 7 0 4 2 5 2]
[6.33 6.   5.67 4.67 3.67 2.   3.67 3.  ]
[6.33 6.   5.67 4.67 3.67 2.   3.67 3.  ]

4.55 填寫缺失的日期

# 問題:給定一系列不連續(xù)的日期序列。填寫缺失的日期戒悠,使其成為連續(xù)的日期序列熬荆。

dates = np.arange(np.datetime64('2018-02-01'), np.datetime64('2018-02-25'), 2)
print(dates)

# Solution ---------------
filled_in = np.array([np.arange(date, (date+d)) for date, d in zip(dates, np.diff(dates))]).reshape(-1)

# add the last day
output = np.hstack([filled_in, dates[-1]])
print(output)

4.56 生成一個二維矩陣

# 問題:從給定的一維數(shù)組arr中,利用步進生成一個二維矩陣绸狐,窗口長度為4卤恳,步距為2,
# 類似于 [[0,1,2,3], [2,3,4,5], [4,5,6,7]..]

def gen_strides(a, stride_len=5, window_len=5):
    n_strides = ((a.size-window_len)//stride_len) + 1
    # return np.array([a[s:(s+window_len)] for s in np.arange(0, a.size, stride_len)[:n_strides]])
    return np.array([a[s:(s+window_len)] for s in np.arange(0, n_strides*stride_len, stride_len)])

a = np.arange(15)
print(a)
print(gen_strides(a, window_len=4, stride_len=2))
運行結果
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
[[ 0  1  2  3]
 [ 2  3  4  5]
 [ 4  5  6  7]
 [ 6  7  8  9]
 [ 8  9 10 11]
 [10 11 12 13]]
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寒矿,一起剝皮案震驚了整個濱河市突琳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌符相,老刑警劉巖拆融,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啊终,居然都是意外死亡镜豹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門蓝牲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趟脂,“玉大人,你說我怎么就攤上這事例衍∥羝冢” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵佛玄,是天一觀的道長硼一。 經(jīng)常有香客問我,道長梦抢,這世上最難降的妖魔是什么欠动? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上具伍,老公的妹妹穿的比我還像新娘翅雏。我一直安慰自己,他們只是感情好人芽,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布望几。 她就那樣靜靜地躺著,像睡著了一般萤厅。 火紅的嫁衣襯著肌膚如雪橄抹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天惕味,我揣著相機與錄音楼誓,去河邊找鬼。 笑死名挥,一個胖子當著我的面吹牛疟羹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播禀倔,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼榄融,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了救湖?” 一聲冷哼從身側響起愧杯,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鞋既,沒想到半個月后力九,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡邑闺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年跌前,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片检吆。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖程储,靈堂內(nèi)的尸體忽然破棺而出蹭沛,到底是詐尸還是另有隱情,我是刑警寧澤章鲤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布摊灭,位于F島的核電站,受9級特大地震影響败徊,放射性物質發(fā)生泄漏帚呼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望煤杀。 院中可真熱鬧眷蜈,春花似錦、人聲如沸沈自。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枯途。三九已至忌怎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間酪夷,已是汗流浹背榴啸。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晚岭,地道東北人鸥印。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像腥例,于是被迫代替她去往敵國和親辅甥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 numpy是支持 Python語言的數(shù)值計算擴充庫燎竖,其擁有強大的高維度數(shù)組處理與矩陣運算能力璃弄。除此之外,nu...
    TensorFlow開發(fā)者閱讀 3,212評論 0 35
  • 1. numpy簡單介紹 numpy 是采用c語言編寫构回,相對python自帶的list數(shù)組,好處是采用的矩陣運算夏块,...
    淘碼小工閱讀 1,225評論 0 1
  • NumPy(Numerical Python) 是 Python 語言的一個擴展程序庫,支持大量的維度數(shù)組與矩陣運...
    Bool吖閱讀 1,138評論 0 3
  • 23. 圖像矩陣去掉一維 reshape(1, width*height).squeeze() 22. 判斷兩個矩...
    謝小帥閱讀 846評論 0 0
  • import numpy as np np.version導入numpy并查看版本 np對象 np.array()...
    萌木蓋閱讀 214評論 0 0