1. 程式人生 > >[開源庫學習] Numpy日記 Section.1

[開源庫學習] Numpy日記 Section.1

前言

   最近開始學習Data anaysis,將numpy入門學習日記分享出來,也當做個記錄。

 【Numpy官網學習地址】:Click Here

   備註:

        我儘可能的將官網快速教程中的case都貼出來了,但越往下越發現這個庫是真的龐大,教程也是由淺及深,後面會涉及到向量、線性代數等高數概念,這個日記中不會提到,需要的話自行前往官網檢視。這個日記分為兩個Section,加起來可能佔到官網快速教程中的case的80%左右,入門Numpy足矣。

    Numpy日記 Section.2


正文

import numpy as np

#基本的幾種陣列建立方式
a = np.arange(0,10) #建立一維陣列
b = a.reshape(2,5)  #臨時變換為二維陣列

a_ = np.array([[1,2,3],range(1,4)])  #建立二維陣列
print(a_,'\n',a_.ndim)  #列印陣列和其維數

a0 = [1,2,4]
aa = np.array(a0)#建立一維陣列


#陣列型別::指定陣列元素型別來建立陣列

a1 = np.float32(range(9))
a1_used_mem = a1.itemsize*a1.size #32/8*9

a2 = np.int_(range(3))
a3 = np.arange(-5,5,dtype=np.uint)

#建立指定size的陣列,zeros,ones,empty
a4 = np.zeros((2,3,4))
a5 = np.ones((2,3,4))
a6 = np.empty((2,3,4))
print(a6,1111)
#三個數表示維數是3,第一個數2表示結果包含兩個2維陣列(維數-1),第二個指定每個二維陣列的列長,
# 第三個指定每個二維陣列的行長(這是shape傳入三個數的情況)


#指定範圍內取指定元素個數生成陣列
a7 = np.linspace(0,2,9,dtype=np.float16)


#列印大型陣列的所有內容
np.set_printoptions(threshold=np.nan)
a8 = np.arange(100000,dtype=np.int_)
a8 = a8.reshape((10,10000))


#陣列的算術運算,例舉部分
a9 = np.array([10,20,30,40])
t = np.arange(4)
a99_ = a9 - t  #差  [10 19 28 37]
a99x = t**2 #冪  [0 1 4 9]
a99sin = np.sin(a9)  #正弦值    [-0.54402111  0.91294525 -0.98803162  0.74511316]

#判斷陣列的每個元素是否滿足某個條件
a10 = np.array([1,2,4,66])
a10_ = 3 < a10  #  [False False  True  True]
a11 = np.array([0,2,4,66])
a11_ = (a10 == a11)  # [False  True  True  True] 不加括號也行

#dot 代表矩陣的乘法運算,點積:dot product
# 計算方式:陣列A的第一行與陣列B的第一列的對應各元素乘積之和->作為結果陣列的第一行第一列位置的元素值。
a10 = np.array([[1,2],
                [4,5]])

a11 = np.array([[2,4],
                [3,2]])

a10_11 = a10.dot(a11) #區別於* ,後者是對應位置元素簡單相乘得到結果陣列
dot_10_11 = np.dot(a10,a11)  #結果同上

# 關於+=  *=的運算方式
a12 = np.ones((3,4),dtype=np.int32)  #int 可換成np.int32,但區別於np.int8 /int16等,數字表示單個元素佔用記憶體的bit大小,8即8bit=1byte
a12 += 9  #該運算會直接修改a12 ,不會產生新變數
a12 *= 2  #a12變成shape 為(3,4)的全20二維陣列

#對兩個不同元素型別的陣列進行算術運算時,結果陣列的元素型別將會是更精確或更常見的那一類。
a13 = np.zeros((2,2),dtype=int) #建立一個二維全0陣列物件
t1 = np.linspace(0,np.pi,4) #建立一個一維陣列,4個元素, np.pi=π=3.141592653589793
t1 = t1.reshape(2,2)   #變換為二維

a13_t1 = a13 + t1  #兩個多維陣列(矩陣)長寬一致/形狀吻合/shape相等,才可以進行算術運算

#print(a13.dtype,t1.dtype)
#a13的dtype是np.int32(=python中的int), t1的是np.float64 ,運算後的結果陣列dtype選擇更精確的float64


#大部分一元運算,如求和,最大最小值等都可以使用np自帶的方法快速實現
a14 = np.random.random((2,3)) #建立一個隨機二維陣列,shape為2,3
a14_sum = a14.sum() #最大a14.max()  最小a14.min()

#如何針對列和行進行運算,如求每列/每行的和、最大最小值
a15 = np.arange(12).reshape(3,4)
a15_col = a15.sum(axis=0)
a15_row = a15.max(axis=1)
#print(a15_col,a15_row)  #[12 15 18 21] [ 3  7 11]


#如何方便的應用數學中的函式,如exp,開平方等
#需要用到np中的通用函式

a16 = np.array([0,1,2])
a16_exp = np.exp(a16) #[ 1. ,  2.71828183,  7.3890561 ]
a16_sqrt = np.sqrt(a16)  #[0.    1.    1.41421356] 對0開方不會報錯
a16_add = np.add(a16,range(3),dtype=float) #[0. 2. 4.]   可直接和list進行算術運算,可以指定dtype


#其他常用操作,如排序
a17 = np.array([[3,2,1],[2,3,0]])
a17_sort = np.sort(a17) #[[1 2 3],[0 2 3]]
a17_sort_no_axis = np.sort(a17,axis=None)  #[0 1 2 2 3 3],轉換為一維陣列
a17_sort_for_col = np.sort(a17,axis=0)  #對每列元素進行排序
a17_sort_for_row = np.sort(a17,axis=1)  #對每行元素排序,等效於np.sort(a17)


#退一取整:floor,進一取整:ceil, 均值
a18 = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
a18_floor = np.floor(a18) #[-2. -2. -1.  0.  1.  1.  2.]  使元素值儘量減小
a18_ceil = np.ceil(a18)  #[-1. -1. -0.  1.  2.  2.  2.]  使元素值儘量增大
a18_ave = np.average(a18) #元素平均值  0.2857142857142857,也可以傳axis引數
print(a18_ave)


#矩陣內的元素累加:cumsum  若不傳參,會將任意大小的矩陣視為一維陣列,
# 然後進行元素累加產生新的一維陣列
a19 = np.arange(12).reshape(3,4)
print(a19)
a19_reduce = a19.cumsum()  #[ 0  1  3  6 10 15...]
# 第一個數不變,第二個數為前兩個數的和,第三個數為前三個數的和,類推


#一維陣列的索引、分片、遍歷 [和list用法大部分一致]
a20 = np.arange(0,20,2)**3  #每個元素進行立方運算
a20_5 = a20[5]
a20_f1 = a20[-1]
a20_5_to_10 = a20[5:10]
a20_3_colon = a20[::2]
for i in a20:print(i)

#多維陣列的索引、分片用法
def f(x,y):
    return 10*x+y
a21 = np.fromfunction(f, (5,4), dtype=int) #使用函式構建一個二維陣列,斷電除錯可觀察構建過程
a21_2 = a21[2]  # 一個一維陣列
a21_comma_2_3 = a21[2,3] # 一個元素
a21_colon_2 = a21[2:3]  # 一個二維陣列
a21_comma_colon_02_f1 = a21[0:2,-1]
a21_comma_colon_f1 = a21[:,-1]
a21_comma_colon_ = a21[:,:] # all

#無逗號時,索引引指定哪個/哪些較低一維的陣列
#逗號分隔時,逗號前的索引指定哪個/哪些較低一維的陣列,逗號後的索引,對前面索引出來的陣列進行再索引,可理解為遞迴索引
#續上一行,例如此處案例是個二維陣列,逗號前的索引就是索引出符合條件的一維陣列,逗號後的索引就是對前者輸出的一維陣列進行再次索引,
# 一維陣列的索引結構就好比list的索引
#若是對一個三維(以上的)陣列進行操作,同理,注意觀察結果

a21_3_ndim = np.zeros((2,3,4)) #建立一個3維陣列,包含兩個2維陣列,每個2維陣列3行4列
a21_3_ndim[0] = 1
#print(a21_3_ndim)
a21_3_ndim[1:2] = 2
#print(a21_3_ndim)
a21_3_ndim[0:1,-1] = 0.5
#print(a21_3_ndim)
a21_3_ndim[-1,2,-1] = 0.1
#只有多維陣列的情況下才會出現2個逗號(以上)的索引用法,因為定位到元素的索引步驟會隨著維度的增加而增加

#3個點的用法:在遇到多維陣列的情況下,[...]可用來代替部分索引的編寫,類似py3中的*rest用法
a21_3_ndim[...,-1] = 0.2 #同 [:,:,-1]
a21_3_ndim[0,0,...] = 0.4 #同 [0,0,:]


# for i in a21_3_ndim:print(i) #對多維(N)陣列進行遍歷的的時候
# 輸出的一級變數遍歷永遠是(N-1)維陣列,若是一維陣列,則直接輸出元素


#高階索引用法 :“陣列索引”
# https://docs.scipy.org/doc/numpy/user/quickstart.html#fancy-indexing-and-index-tricks
a22 = np.array([[1, 2], [3, 4], [5, 6]]) #一個二維陣列
a22_ad_index_1 = a22[[0,1,2],[0,1,0]] #[1 4 5] 第一個陣列進行第一次索引,第二個陣列對前者得出的結果進行二次索引,多練習可領會
a22_ad_index_2 = a22[[0],[0]] #[1]
a22_ad_index_3 = a22[[0]] #[[1 2]]

#高階索引得到的結構始終是一個ndarray物件
a22_t = np.ones((5,4,5))  #建立一個3維陣列,包含5個2維陣列,每個2維陣列4行5列
#print(a22_t)
a22_t[[-2,-1], [0,1]] = 2
#print(a22_t)
a22_t[[-2,-1], [0,1], [1,2]] = 3
#print(a22_t)

#高階索引之布林型別索引
a22_t1 = np.arange(4)
a22_t1[a22_t1>1] = 6
print(a22_t1)  #[0 1 6 6]


#取出每列或每行中最大(小)值的索引
a22_t2 = np.array([range(3),range(3,6),[2,11,1]])
print(a22_t2)
print(a22_t2.argmax(axis=1))  #[2 2 1]
#axis=0表示按列,  1表示按行  , argmin:取出最小值的索引
哪兒不對或者有疑問,各位老鐵可以留言,我會盡量回復。