【Python數據分析之Numpy02】利用數據進行數據處理

矢量化計算

    概念是:用數組表達式代替循環。

    例:計算點(x,y)到原點的長度。首先介紹一個函數,np.meshgrid(*x,*y)。這個函數接收兩個數組*x,*y,對於這兩個數組上的所有元素,進行一一對應,生成兩個矩陣,兩個矩陣相同位置上的元素就是點的x和y座標。

points = np.arange(-5,5,0.01,dtype=np.float64)
xs,ys = np.meshgrid(points,points)
xs
'''
結果:
array([[-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       ...,
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99],
       [-5.  , -4.99, -4.98, ...,  4.97,  4.98,  4.99]])
ys是xs的轉置
'''

    下面就是調用np.sqrt對數組進行處理:

z = np.sqrt(xs ** 2+ys ** 2)
print(z)
'''
結果:
[[7.07106781 7.06400028 7.05693985 ... 7.04988652 7.05693985 7.06400028]
 [7.06400028 7.05692568 7.04985815 ... 7.04279774 7.04985815 7.05692568]
 [7.05693985 7.04985815 7.04278354 ... 7.03571603 7.04278354 7.04985815]
 ...
 [7.04988652 7.04279774 7.03571603 ... 7.0286414  7.03571603 7.04279774]
 [7.05693985 7.04985815 7.04278354 ... 7.03571603 7.04278354 7.04985815]
 [7.06400028 7.05692568 7.04985815 ... 7.04279774 7.04985815 7.05692568]]
'''

    嘗試將其可視化,提前感受一下(雖然這個函數我看不懂):


將條件邏輯表述爲數組運算

    np.where(condition,x,y)(注意順序)函數是x if condition else y表達式的矢量化(數組版),但它的參數可以不是數組。

    例:首先有這樣三個數組:

x = np.array([1.1,1.2,1.3,1.4,1.5])
y = np.array([2.1,2.2,2.3,2.4,2.5])
cond = np.array([True,False,True,True,False])

    若想要實現cond爲True時從x選取,cond爲False時從y選取,傳統Python解決方式爲:

result = [(x if z else y)
            for x,y,z in zip(x,y,cond)]
result
#結果:[1.1, 2.2, 1.3, 1.4, 2.5]

    看着是沒什麼毛病,但是很顯然,當數組很大時,for循環佔用空間大的缺點就暴露出來了。若用np.where,不僅能處理大叔組,寫起來也很簡潔:

result_wh = np.where(cond,x,y)
result_wh
#結果:[1.1, 2.2, 1.3, 1.4, 2.5]

    np.where函數能夠處理更復雜的邏輯問題,將來若有需要希望別忘了它。

數學統計方法

arr = np.random.randn(5,4)

#求算數平均數
arr.mean()
#結果:-0.10653246371327466

#求所有元素之和
arr.sum()
#結果:-2.0196217215714967

    這兩種方法接收一個axis參數,這樣計算的就是該軸上的統計值:

#求某軸向的所有元素的和
arr.sum(axis=0)
#array([-0.75673429,  1.70129588, -0.95407974, -4.86702506])
arr.sum(1)
#array([-0.58449652, -0.50289763, -0.21146403, -3.79389472,  0.21620969])

    還有一些其他方法:

    std:求標準差            var:求方差

    min,max:求最小值和最大值

    argmin,argmax:求最小值和最大值的索引

    cumsum:所有元素的累計和(每一維或每個數累積一次)

    cumprod:所有元素的累計積

arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr.cumsum())
#[ 1  3  6 10 15 21 28 36 45]
print(arr.cumsum(0))
'''
[[ 1  2  3]
 [ 5  7  9]
 [12 15 18]]
'''

排序

    數組排序運用的也是sort就地排序(即會改動數組),同樣,sort也支持在一個軸向上排序。

arr = np.random.randn(5,3)
print(arr)

print('*'*40)

arr.sort(1)
print(arr)

'''
結果:
[[ 2.16177016  0.08249236 -0.2261361 ]
 [-0.55112602 -1.6953063   0.77323005]
 [-0.21736826 -0.26397035  1.20148955]
 [-1.97900358 -0.90121201  0.21595791]
 [ 1.28279156  0.69281414  2.59958602]]
****************************************
[[-0.2261361   0.08249236  2.16177016]
 [-1.6953063  -0.55112602  0.77323005]
 [-0.26397035 -0.21736826  1.20148955]
 [-1.97900358 -0.90121201  0.21595791]
 [ 0.69281414  1.28279156  2.59958602]]
'''

其他集合邏輯

    *注意!這些函數僅僅用於一維數組!

    np.unique():計算x中的唯一元素(即去掉重複值),並返回有序結果。

a = np.array([34,235,54,23,43,23,4,5,235,5])
np.unique(a)
#結果:array([  4,   5,  23,  34,  43,  54, 235])

    np.in1d(*x,*y):測試數組x在數組y中的成員資格。

    intersect1d(*x,*y):計算x,y的公共元素,並返回有序結果。

    union1d(*x,*y):計算x,y的並集,並返回有序結果。

    in1d(*x,*y):得到一個表示“x的元素是否包含於y”的bool型數組。

    setdiff1d(*x,*y):集合的差,x-y。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章