iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 8
0
AI & Data

python 入門到分析股市系列 第 8

[Day08]Learning Numpy - Ufuncs、broadcasting、運算子

  • 分享至 

  • xImage
  •  

前言

今天是鐵人賽的第八天,昨天介紹了如何建立Numpy的陣列,和陣列的一些基本屬性(size、shape...),和兩個以上的陣列可以如何合併和分割,今天要來介紹Numpy的函式。


Ufuncs

Numpy陣列中的計算,許多Ufuncs都是在C程式實作,計算速度比較快,接下來介紹一些比較常用的Ufuncs

絕對值:abs()

x = np.array([-2,-1,0,1,-3])
abs(x)
# 輸出結果
array([2, 1, 0, 1, 3])

三角函數:abs()、cos()、tan()

theta = np.linspace(0, np.pi, 3)  #建立一個角度的陣列
print("sin()---->", np.sin(theta))
print("cos()---->", np.cos(theta))
print("tan()---->", np.tan(theta))
# 輸出結果
sin()----> [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos()----> [ 1.000000e+00  6.123234e-17 -1.000000e+00]
tan()----> [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]

指數和對數:exp()、exp2()、power()、log()、log2()、log10()

x = [1,2,9,10, 16]
print("exp()---->", np.exp(x))          # e^x
print("exp2()---->", np.exp2(x))        # 2^x
print("power()---->", np.power(3, x))   # 3^x
print("log()---->", np.log(x))          # log自然對數
print("log2()---->", np.log2(x))        # 以2為基底的對數
print("log10()---->", np.log10(x))      # 以10為基底的對數
# 輸出結果
exp()----> [2.71828183e+00 7.38905610e+00 8.10308393e+03 2.20264658e+04
 8.88611052e+06]
exp2()----> [2.0000e+00 4.0000e+00 5.1200e+02 1.0240e+03 6.5536e+04]
power()----> [       3        9    19683    59049 43046721]
log()----> [0.         0.69314718 2.19722458 2.30258509 2.77258872]
log2()----> [0.         1.         3.169925   3.32192809 4.        ]
log10()----> [0.         0.30103    0.95424251 1.         1.20411998]

外積:outer()

y = np.arange(1,6)
np.multiply.outer(y, y)
# 輸出結果
array([[ 1,  2,  3,  4,  5],
       [ 2,  4,  6,  8, 10],
       [ 3,  6,  9, 12, 15],
       [ 4,  8, 12, 16, 20],
       [ 5, 10, 15, 20, 25]])

sum():陣列做加總

如果想要計算陣列中所有元素的加總,可以使用sum()

import numpy as np
L = np.random.random(100)  #在0到1間亂數值取100個
np.sum(L)
# 輸出結果
48.87105412779822

sum()除了可以使用一維陣列,現在用多維陣列

m = np.random.random((3,4))
print(m)
print('column 加總', m.sum(axis=0)) #column加總
print('row 加總', m.sum(axis=1)) #row加總
# 輸出結果
[[0.90141178 0.44072501 0.5813923  0.06718993]
 [0.74907766 0.65631017 0.47611455 0.33805445]
 [0.79914804 0.9814414  0.23869758 0.10919935]]
column 加總 [2.44963747 2.07847657 1.29620443 0.51444374]
row 加總 [1.99071901 2.21955683 2.12848637]

min(),max():陣列中的最大值和最小值

取得陣列中元素的最大值和最小值

ironman_int = np.random.randint(0,10000,200) #在整數0~10000之間取值200個
print('min---->', np.min(ironman_int))
print('max---->', np.max(ironman_int))
min----> 22
max----> 9946

min()、max()除了可以使用一維陣列,現在用多維陣列

ironman_int_multi = np.random.randint(0,10000,(3,4)) #建立3*4的陣列,值介在整數0~10000之間
print('ironman_int_multi---->', ironman_int_multi)

print('ironman_int_multi.min(axis=0)----->', ironman_int_multi.min(axis=0))
print('ironman_int_multi.max(axis=1)----->', ironman_int_multi.max(axis=1))
# 輸出結果
ironman_int_multi----> [[9931 4228 5996 3076]
 [2969 9102  374 1900]
 [5982 1051 9939 4320]]
ironman_int_multi.min(axis=0)-----> [2969 1051  374 1900]
ironman_int_multi.max(axis=1)-----> [9931 9102 9939]
  • 比較np.min和min
    之前在第二天的時候有學到也可以使用Python內建的min()來取得陣列的最小值,在這邊比較兩者運算所耗費的時間。
big_array = np.random.random(10000000) #在0到1間亂數值取10000000個
%timeit min(big_array)
%timeit np.min(big_array)
# 輸出結果
612 ms ± 23.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
7.38 ms ± 1.04 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

Numpy其他陣列計算函式

名稱 說明
np.sum 所有元素的加總
np.prod 所有元素的乘積
np.mean 所有元素的平均值
np.std 標準差
np.var 變異量
np.min 找出元素的最小值
np.max 找出元素的最大值
np.argmin 找出最小值的索引
np.argmax 找出最大值的索引
np.median 元素的中位數
np.any 當陣列中有任一值是True或是非零值時傳回True
np.all 當陣列中有所有值是True或是非零值時傳回True

broadcasting

numpy的陣列具有broadcasting的特性,為了就是當不同shape的陣列可以進行運算。陣列可以做的運算只有(+,-),當使用乘法運算時兩個ndarray必須相同的shape

a = np.array([0,1,2])
a + 5
# 輸出結果
array([5, 6, 7])

上述的例子,可以想像成將數值5拉長成[5,5,5],然後再與a相加到執行結果
下面用更加複雜的例子

a = np.arange(3)
b = np.arange(3)[:, np.newaxis]
print(a)
print(b)
print(a+b)
# 輸出結果
[0 1 2]
[[0]
 [1]
 [2]]
[[0 1 2]
 [1 2 3]
 [2 3 4]]

比較運算子(==,!=,<,<=,>,>=)

以下建立一個ndarray,並且比較其中元素大於2

x = np.array([1,2,3,4,5])
x>2
# 輸出結果
array([False, False,  True,  True,  True])

對於比較結果也可計算,計算大於2的有幾個

np.count_nonzero(x>2)
# 輸出結果
3

除了使用count_nonzero計算數量,也可使用sum做運算,好處是可以針對欄或列運算,以下範例是每一列大於5的計數。

x = np.random.randint(10, size=(3,4))
print(x)
np.sum(x>5,axis = 1)
# 輸出結果
[[0 7 2 8]
 [8 9 3 9]
 [8 0 2 1]]
array([2, 3, 1])

如果想要執行陣列中所有的值是否都小於8,用上述的x當陣列

np.all(x<8,axis = 0)
# 輸出結果
array([False, False,  True, False])

邏輯運算子(&,|,^,~)

當計算陣列中的元素需要符合兩個以上條件,ex 陣列中 > 5 且 < 8 的元素計算,就需要透過邏輯運算子來完成。
以下範例是算出數值大於5且小於8

x = np.random.randint(10, size=(4,5))
print(x)
np.sum((x > 5) & (x <8))
# 輸出結果
[[4 2 2 4 0]
 [4 7 0 1 4]
 [9 1 7 6 9]
 [4 3 7 7 8]]
5

遮罩: 回傳特定條件的陣列

上述的例子可以學到使用陣列和比較運算子運算後傳回布林的陣列。現在要用回傳的布林運算子來取得想要的元素陣列。
以下範例是回傳大於5且小於8

x = np.random.randint(10, size=(4,5))
print(x)
x[(x>5) & (x <8)]
# 輸出結果
[[2 5 7 4 7]
 [6 2 3 9 3]
 [9 9 7 8 8]
 [2 6 8 3 3]]
array([7, 7, 6, 7, 6])

之前的章節導覽

  • 安裝環境
  • Numpy
  • 程式碼位置
    • github
      因為作者本身也是第一次學習Python和寫程式文章,所以編排上會有點亂,觀念可能也會錯誤,如果有疑問可以提出一起討論,等30天完成之後有其他時間會將之前寫的文章加入一些想法。

上一篇
[Day07]Learning Numpy - 建立、合併、分割
下一篇
[Day09]Learning Numpy - Fancy、sort、structured array
系列文
python 入門到分析股市30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Andy Chiu
iT邦研究生 3 級 ‧ 2018-11-08 12:50:25

這個部分的內容怪怪的,好像少了什麼


sum()除了可以使用一維陣列,現在用多維陣列

m.min(axis=0) #0軸最小值
m.max(axis=1) #1軸最大值
Summer iT邦新手 5 級 ‧ 2018-11-08 13:43:47 檢舉

不好意思,已經修正,貼錯程式了,已經做修正。/images/emoticon/emoticon20.gif

大大真的很細心。非常感謝。

我要留言

立即登入留言