numpy的函式用法
1.nump的where
第一種用法
np.where(conditions,x,y)
if (condituons成立):
陣列變x
else:
陣列變y
eg:滿足結果中key為‘a’的值中字串含有window的則輸出windows,否則輸出為Not Windows
operating_system=np.where(cfram['a'].str.contains('Windows'),'Windows','Not Windows')
輸出結果為:[‘Windows’ ‘Not Windows’ ‘Windows’ ‘Not Windows’ ‘Windows’]
第二種用法:用if..elif..else處理太醜,用where很簡便
eg:
cond2 = np.array([True,False,True,False])
cond1 = np.array([True,True,False,False])
result = []
for i in range(4):
if (cond1[i] & cond2[i]): result.append(0);
elif (cond1[i]): result.append(1);
elif (cond2[i]): result.append(2);
else : result.append(3);
print(result)
用where只要一句話
result = np.where(cond1 & cond2,0,np.where(cond1,1,np.where(cond2,2,3)))
輸出結果:[0, 1, 2, 3]
2.numpy.loadtext
作用是把文字檔案(*.txt)讀入並以矩陣或向量的形式輸出。它有幾個引數:skiprows,delimiter,usecoles和unpack。skiprows作用是跳過頭行。在預設情況下是通過空格來分割列的,如果想通過其他來分割列則需要通過delimiter來設定。如果你想跳過幾列來讀取則需要用usecoles來設定。
正常情況下該返回的是二維矩陣,若設定了unpack=True將返回各列。
np.loadtxt('loadtxt.txt', skiprows=1,delimiter=',')
返回結果
array([[ 1., 2., 3., 4.], array([[ 4., 7., 5., 9.],
[ 4., 7., 5., 9.], [ 7., 2., 2., 2.]])
[ 7., 2., 2., 3.]])
from io import StringIO # StringIO behaves like a file object
c=StringIO(u"0 1\n2 3")
print np.loadtxt(c)
結果:
[[ 0. 1.]
[ 2. 3.]]
3.numpy.reshape
#建立一個數組
a=np.array([1,2,3,4,5,6,7,8])
print a
#輸出結果是:[1 2 3 4 5 6 7 8]
使用reshape()方法來更改陣列的形狀,可以看到看陣列d成為了一個二維陣列
d=a.reshape((2,4))
print d
#輸出結果如下:
[[1 2 3 4]
[5 6 7 8]]
通過reshape生成的新陣列和原始陣列公用一個記憶體,也就是說,假如更改一個數組的元素,另一個數組也將發生改變
a[1]=100
print a
print d
#輸出結果如下:
[ 1 100 3 4 5 6 7 8]
[[ 1 100 3 4]
[ 5 6 7 8]]
同理還可以得到一個三維陣列
c=a.reshape((2,2,2))
print c
#輸出結果:
[[[ 1 100]
[ 3 4]]
[[ 5 6]
[ 7 8]]]
形狀變化的原則是陣列元素不能發生改變,比如這樣寫就是錯誤的,因為陣列元素髮生了變化
c=a.reshape((2,2,3))
print c
#報錯,因為總共8個元素,分成3個2行2列的元素,則要2*2*3=12個元素才可以
reshape((-1,1))相當於一行的陣列轉置
b=np.arange(0,60,10).reshape((-1,1))
#結果如下:
[[ 0]
[10]
[20]
[30]
[40]
[50]]
#故下面是相當於[0,1,2,3,4,5]+上面單列的轉置矩陣
a = np.arange(0, 60, 10).reshape((-1, 1)) + np.arange(6)
#得到結果如下:
[[ 0 1 2 3 4 5]
[10 11 12 13 14 15]
[20 21 22 23 24 25]
[30 31 32 33 34 35]
[40 41 42 43 44 45]
[50 51 52 53 54 55]]
4.陣列的元素型別可以通過dtype屬性獲得
# 通過array函式傳遞list物件
L = [1, 2, 3, 4, 5, 6]
print("L = ", L)
a = np.array(L)
print("a = ", a)
輸出結果('a = ', array([1, 2, 3, 4, 5, 6]))
print(a.dtype)
輸出結果:int64
可以通過dtype引數在建立時指定元素型別
d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float)
f = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.complex) #指定元素型別為複數
5.如果更改元素型別,可以使用astype安全的轉換
d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float)
f = d.astype(np.int)
print(f)
#結果:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
#若用下面的直接轉,不會報錯,但出現一堆亂七八糟的數字
#但不要強制僅修改元素型別,如下面這句,將會以int來解釋單精度float型別
d.dtype = np.int
print(d)
6.numpy.arange
arange函式類似於python的range函式:指定起始值、終止值和步長來建立陣列.和Python的range類似,arange同樣不包括終值;但arange可以生成浮點型別,而range只能是整數型別.
np.set_printoptions(linewidth=100, suppress=True) #輸出列印的格式
a = np.arange(1, 10, 0.5)
print(a)
7.numpy.linespace
通過指定起始值、終止值和元素個數來建立陣列,預設包括終止值
b = np.linspace(1, 10, 10)
print('b = ', b)
#結果
('b = ', array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]))
# 可以通過endpoint關鍵字指定是否包括終值
c = np.linspace(1, 10, 10, endpoint=False)
print('c = ', c)
#結果:
('c = ', array([ 1. , 1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1]))
8.numpy.logspace可以建立等比數列
# 下面函式建立起始值為10^1,終止值為10^2,有10個數的等比數列
d = np.logspace(1, 4, 4, endpoint=True, base=2)
print(d)
# 下面建立起始值為2^0,終止值為2^10(包括),有10個數的等比數列
f = np.logspace(0, 10, 11, endpoint=True, base=2)
print(f)
9.使用 frombuffer, fromstring, fromfile等函式可以從位元組序列建立陣列
s = 'abcdzzzz'
g = np.fromstring(s, dtype=np.int8) #以Ascii碼轉換
print(g)
#結果:字母對應的Ascii碼值
[ 97 98 99 100 122 122 122 122]
10.存取資料
切片存取和python一樣
a = np.arange(10)
print(a)
# 獲取某個元素
print(a[3])
# 切片[3,6),左閉右開
print(a[3:6])
# 省略開始下標,表示從0開始
print(a[:5])
# 下標為負表示從後向前數
print(a[3:])
# 步長為2
print(a[1:9:2])
# 步長為-1,即翻轉
print(a[::-1])
# 切片資料是原陣列的一個檢視,與原陣列共享內容空間,可以直接修改元素值
a[1:4] = 10, 20, 30
print(a)
# 因此,在實踐中,切實注意原始資料是否被破壞,如:
b = a[2:5]
b[0] = 200
print(a)
11.整數/布林陣列存取
11.1根據整數陣列存取:當使用整數序列對陣列元素進行存取時,
將使用整數序列中的每個元素作為下標,整數序列可以是列表(list)或者陣列(ndarray)。
使用整數序列作為下標獲得的陣列不和原始陣列共享資料空間。
a = np.logspace(0, 9, 10, base=2)
print(a)
i = np.arange(0, 10, 2)
print(i)
# 利用i取a中的元素
b = a[i]
print(b)
#返回結果
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
[0 2 4 6 8]
[ 1. 4. 16. 64. 256.]
#b的元素更改,a中元素不受影響
b[2] = 1.6
print(b)
print(a)
#返回結果:
[ 1. 4. 1.6 64. 256. ]
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
11.2布林存取
使用布林陣列i作為下標存取陣列a中的元素:返回陣列a中所有在陣列b中對應下標為True的元素。生成10個滿足[0,1)中均勻分佈的隨機數。
a = np.random.rand(10)
print(a)
# 大於0.5的元素索引
print(a > 0.5) #判斷a是否>5,若大於5返回True
#返回結果:
[ True False True True True True True False False True]
# 大於0.5的元素
b = a[a > 0.5] #取a[True]的元素,即全是a>0.5的元素
print(b) #b全是取出a陣列中>0.5的元素
# 將原陣列中大於0.5的元素擷取成0.5
a[a > 0.5] = 0.5
print(a)
# b不受影響
print(b) #b還是前面取出a陣列中>0.5的元素
12.二維陣列的切片
# [[ 0 1 2 3 4 5]
# [10 11 12 13 14 15]
# [20 21 22 23 24 25]
# [30 31 32 33 34 35]
# [40 41 42 43 44 45]
# [50 51 52 53 54 55]]
a = np.arange(0, 60, 10) # 行向量
print('a = ', a)
b = a.reshape((-1, 1)) # 轉換成列向量
print(b)
c = np.arange(6)
print(c)
# f = b + c # 行 + 列
print(f)
# # 合併上述程式碼:
a = np.arange(0, 60, 10).reshape((-1, 1)) + np.arange(6)
print(a)
# 二維陣列的切片
print(a[[0, 1, 2], [2, 3, 4]]) #取第0行2列,1行3列,2行4列資料
#結果
[ 2 13 24]
print(a[4, [2, 3, 4]]) #取第4行2列,4行3列,4行4列資料
#結果
[42 43 44]
print(a[4:, [2, 3, 4]]) #從第4行列始,後面的2,3,4列資料。a總共5行,故取4行2列,4行3列,4行4列,5行2列,5行3列,5行4列
#結果
[[42 43 44]
[52 53 54]]
i = np.array([True, False, True, False, False, True])
#取True的值,i是行向量,即取第一行,第3行,最後一行
print(a[i])
#結果
[[ 0 1 2 3 4 5]
[20 21 22 23 24 25]
[50 51 52 53 54 55]]
print(a[i, 3])取a[i]行的第4列數,下標是從0開始的
#結果
[ 3 23 53]
13.numpy與Python數學庫的時間比較
numpy比python快多了,因為numpy中ndarray是C++寫的。
for j in np.logspace(0, 7, 8):
x = np.linspace(0, 10, j)
start = time.clock()
y = np.sin(x)
t1 = time.clock() - start
x = x.tolist()
start = time.clock()
for i, t in enumerate(x):
x[i] = math.sin(t)
t2 = time.clock() - start
print(j, ": ", t1, t2, t2/t1)
14.元素去重unique
a = np.array((1, 2, 3, 4, 5, 5, 7, 3, 2, 2, 8, 8))
print('original array:', a)
# 使用庫函式unique
b = np.unique(a)
print(u'去重後:', b)
#結果:
array([1, 2, 3, 4, 5, 7, 8])
二維陣列的去重,結果會是預期的麼?
c = np.array(((1, 2), (3, 4), (5, 6), (1, 3), (3, 4), (7, 6)))
print('二維陣列:\n', c)
print('去重後:', np.unique(c))
#結果
array([[1, 2],
[3, 4],
[5, 6],
[1, 3],
[3, 4],
[7, 6]])
#去重後並非我們預期的去掉[3,4]:array([1, 2, 3, 4, 5, 6, 7])
解決辦法:方案1:轉換為虛數
print len(np.split(c, (1, ), axis=1)) #按1,分割,縱向分割,len檢視返回幾個值,前面好賦值
r, i = np.split(c, (1, ), axis=1)
print r #1,3,5,1,3,7第一列的縱向量
print i #第二列的縱向量
x = r + i * 1j #第一列+第二列.j 將其轉換成複數,但是是縱向量
print x
x = c[:, 0] + c[:, 1] * 1j #複數行向量
print('轉換成虛數:', x)
print('虛數去重後:', np.unique(x)) #複數可用Unique去重
print(np.unique(x, return_index=True)) #return_index是Ture表示同時返回原始陣列中的下標
#Return_inverse: True表示返冋重建原始陣列用的下標陣列
idx = np.unique(x, return_index=True)[1] #【1】是取未重複陣列下標
print idx
print('二維陣列去重:\n', c[idx]) #取c陣列中idx下標的元素,即該下標已經計算出去重後的下標
#結果
array([[1, 2],
[1, 3],
[3, 4],
[5, 6],
[7, 6]])
解決辦法:方案2:利用set
set是一個無序且不重複的元素集合。集合物件是一組無序排列的可雜湊的值,集合成員可以做字典中的鍵。可變陣列都是不可以做雜湊,故要將array/list轉成tuple不可變長,再設定成set集合
print('去重方案2:\n', np.array(list(set([tuple(t) for t in c]))))
#結果:
array([[1, 2],
[1, 3],
[3, 4],
[5, 6],
[7, 6]])
15.stack and axis 堆疊
a = np.arange(1, 7).reshape((2, 3))
b = np.arange(11, 17).reshape((2, 3))
c = np.arange(21, 27).reshape((2, 3))
d = np.arange(31, 37).reshape((2, 3))
print('a = \n', a)
print('b = \n', b)
print('c = \n', c)
print('d = \n', d)
s = np.stack((a, b, c, d), axis=0)
print('axis = 0 ', s.shape, '\n', s)
s = np.stack((a, b, c, d), axis=1)
print('axis = 1 ', s.shape, '\n', s)
s = np.stack((a, b, c, d), axis=2)
print('axis = 2 ', s.shape, '\n', s)
#結果:
解:axis=0,還是原來的矩陣,shape為(4, 2, 3)4個2行3列矩陣。axis=1,(2, 4, 3)第0列和第一列換,即2個4行3列矩陣。取各種的第一行元素疊加。axis=2,(2, 3, 4)取axis=1時的值再第2列和第3列互換,即2個3行4列矩陣。從axis=0中取每個塊中的列的第一個數。axis=-1也為(2, 3, 4)和axis=2取的元素一樣
('axis = 0 ', (4, 2, 3), '\n', array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[11, 12, 13],
[14, 15, 16]],
[[21, 22, 23],
[24, 25, 26]],
[[31, 32, 33],
[34, 35, 36]]]))
('axis = 1 ', (2, 4, 3), '\n', array([[[ 1, 2, 3],
[11, 12, 13],
[21, 22, 23],
[31, 32, 33]],
[[ 4, 5, 6],
[14, 15, 16],
[24, 25, 26],
[34, 35, 36]]]))
('axis = 2 ', (2, 3, 4), '\n', array([[[ 1, 11, 21, 31],
[ 2, 12, 22, 32],
[ 3, 13, 23, 33]],
[[ 4, 14, 24, 34],
[ 5, 15, 25, 35],
[ 6, 16, 26, 36]]]))
15.np.dot 點選
np.dot([1,2,3],[4,5,6]) = 1*4 + 2*5 + 3*6 = 32
16.陣列拼接
numpy.concatenate((a1,a2,…), axis=0)
注:a.T表示a的轉置
>>> a=np.array([1,2,3])
>>> b=np.array([11,22,33])
>>> c=np.array([44,55,66])
>>> np.concatenate((a,b,c),axis=0) # 預設情況下,axis=0可以不寫
array([ 1, 2, 3, 11, 22, 33, 44, 55, 66]) #對於一維陣列拼接,axis的值不影響最後的結果
>>> a=np.array([[1,2,3],[4,5,6]])
>>> b=np.array([[11,21,31],[7,8,9]])
>>> np.concatenate((a,b),axis=0)
array([[ 1, 2, 3],
[ 4, 5, 6],
[11, 21, 31],
[ 7, 8, 9]])
>>> np.concatenate((a,b),axis=1) #axis=1表示對應行的陣列進行拼接
array([[ 1, 2, 3, 11, 21, 31],
[ 4, 5, 6, 7, 8, 9]])
15.numpy的基礎用法彙總
#coding=utf-8
__author__ = 'mac'
import numpy as np
#python中list中可以有字元,數字等型別。故每次都要判斷list的型別,並且轉換,所以會慢。而ndarray中只能同一種資料型別
lst=[[1,3,6],[2,4,6]]
print type(lst)
np_lst=np.array(lst)
print (type(np_lst))
np_lst=np.array(lst,dtype=np.float) #dtype可以指定資料型別
print (np_lst.shape) #shape型狀,(2,3)2行3列
print (np_lst.ndim) #ndim維數
print (np_lst.dtype) #dtype數居型別
print (np_lst.itemsize) #itemsize每個元素的大小,float64,那每個元素是8個位元組,故為8
print (np_lst.size) #size的大小,該陣列中總共有6個數,則size大小為6
#numpy的some Arrays一些陣列
print (np.zeros([2,4])) #生成2行4列的0矩陣
print (np.ones([3,5])) #生成3行5列的都是1的矩陣
print ('Rand:') #隨機數:生成均勻分佈的資料
print (np.random.rand(2,4)) #生成2行4列的隨機數,裡面的資料都是均勻分佈的
print (np.random.rand()) #不加任何引數只打印了一個隨機數
print ('RandInt:') #隨機整數
print (np.random.randint(1,10,3)) #因為是生成隨機整數,故引數不能為空。生成1-10,不包括10的3個整數
print (np.random.randint(1,10)) #只生成一個隨機整數,從1-10,不包括10
print ('Randn:') #隨機數:標準正態分佈
print (np.random.randn(2,4)) #生成2行4列的標準正態分佈的隨機數
print ('Choice:') #生成指定的隨機數,值只能從給出的隨機數中選擇
print (np.random.choice([10,20,30])) #生成的隨機數只能是10,20,30中選擇
print ('Distribute:') #生成一些數學常用的分佈:二項分佈等
print (np.random.beta(1,10,100)) #從1-10生成100個beta分佈的資料
#3 Array opes 陣列的操作
print (np.arange(1,11)) #生成1-10的等差數列
print (np.arange(1,11).reshape(2,5)) #reshape生成2行5列的1-10的陣列
print (np.arange(1,11).reshape(2,-1)) #-1表示的預設值,結果是和上面一樣生成2行5列的陣列
#python中的lst只能追加,不能對裡面的元素進行相加等操作,但ndarray是可以對裡面的元素進行操作的
print (np.exp(lst)) #exp指數操作,此處np是已經把lst轉化為ndarray了,故可以做指數操作
print (np.exp2(lst))
print (np.sqrt(lst)) #開方
print (np.sin(lst)) #sin
print (np.log(lst)) #對數
#axis=0,1,2的解釋.axis是和陣列的維數有關,最大是到維數-1。
#注:axis越大則深入就越大,axis=0取最外層的陣列
#下面是3個2維4列的陣列
lst=np.array([[[1,2,3,4],
[4,5,6,7]],
[[7,8,9,10],
[10,11,12,13]],
[[14,15,16,17],
[18,19,20,21]]
])
#axis=0是取最外層的陣列:若是求sum就是下面3個數組相加
# [[1,2,3,4],
# [4,5,6,7]]+
# [[7,8,9,10],
# [10,11,12,13]]+
# [[14,15,16,17],
# [18,19,20,21]]
# sum求和1+7+14=22 2+8+15=25 3+9+16=28....
print (lst.sum(axis=0))
#結果如下:
# [[22 25 28 31]
# [32 35 38 41]]
#axis=1是取次外層的陣列:2維的求和操作
# [1,2,3,4], +
# [4,5,6,7] 求和:1+4 2+5,3+6,4+7
# [7,8,9,10], +
# [10,11,12,13] 求和:7+10,8+11,9+12,10+13
# [14,15,16,17], +
# [18,19,20,21] 求和:14+18 15+19 16+20 17+21
print (lst.sum(axis=1))
#結果如下:
# [[ 5 7 9 11]
# [17 19 21 23]
# [32 34 36 38]]
#axis=2時再取第二內層的陣列:
# [1,2,3,4] 求和:1+2+3+4=10
# [4,5,6,7] 求和:4+5+6+7=22
# [7,8,9,10] 求和:7+8+9+10= 34
# [10,11,12,13] 求和:10+11+12+13 =46
# [14,15,16,17] 求和:14+15+16+17 =62
# [18,19,20,21] 求和:18+19+20+21 =78
print (lst.sum(axis=2))
#結果如下:
# [[10 22]
# [34 46]
# [62 78]]
print ('Max:')
print (lst.max(axis=1))
#結果如下:
# Max:
# [[ 4 5 6 7]
# [10 11 12 13]
# [18 19 20 21]]
print ('Min:')
print (lst.min(axis=2))
#結果如下:
# Min:
# [[ 1 4]
# [ 7 10]
# [14 18]]
lst1=np.array([10,20,30,40])
lst2=np.array([4,3,2,1])
#對兩個陣列相加
print ('Add:') #兩個數組裡的元素相加
print (lst1+lst2)
print ('Sub:') #兩個陣列元素相減
print (lst1-lst2)
print ('Mul:') #兩個陣列元素相乘
print (lst1*lst2)
print ('Div:') #兩個陣列元素相除
print (lst1/lst2)
print ('Square:') #取平方
print (lst1**2)
print ('Dot:') #點乘
print (np.dot(lst1.reshape([2,2]),lst2.reshape([2,2])))
# [10,20] [4,3] [4*10+20*2,10*3+20]
# [30,40] * [2,1] = [30*4+2*40,30*3+40]
#點乘結果如下:
# Dot:
# [[ 80 50]
# [200 130]]
print ('Cancatenate:') #像python中的追加,即合在一個數組中
print (np.concatenate((lst1,lst2),axis=0)) #將lst2追到lst1後面,生成一維的陣列
#結果如下:
# Cancatenate:
# [10 20 30 40 4 3 2 1]
print (np.vstack((lst1,lst2))) #vstack一整行陣列追加。原來兩個一行的現在換成兩行
#結果如下:
# [[10 20 30 40]
# [ 4 3 2 1]]
print (np.hstack((lst1,lst2))) #原來兩個一行的現在換成一個數組,和concatenate一樣和append的效果一樣
#結果如下:
#[10 20 30 40 4 3 2 1]
print (np.split(lst1,2)) #split拆分將lst1分成2個數組
# 結果如下:
# [array([10, 20]), array([30, 40])]
print (np.copy(lst1)) #copy拷貝陣列lst1
16.線性代數在numpy中的應用
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
from numpy.linalg import inv,qr
x=np.array([[1.,2.,3.],[4.,5.,6.]])
y=np.array([[6.,23.],[-1,7],[8,9]])
print x,y
print x.dot(y)
print np.dot(x,np.ones(3))
x=random.randn(5,5)
mat=x.T.dot(x)
print inv(mat)
print mat.dot(inv(mat))
q,r=qr(mat)
print r
常用Numpy.linalg函式(線性代數中用到的方法)
diag 以一維陣列的形式返回方陣的對角線(或非對角線)元素,或將一維陣列轉換為方陣(非對角線元素為0)
dot 矩陣乘法
trace 計算對角線元素的和
det 計算矩陣行列式
eig 計算方陣的本徵值和本徵向量
inv 計算方陣的逆
pinv 計算矩陣的Moore-Penrose偽逆
qr 計算QR分解
svd 計算奇異值分解(SVD)
solve 解線性方程組Ax=b,其中A為一個方陣
lstsq 計算Ax=b的最小二乘解
17.numpy中的cumsum函式的用法
cumsum陣列內的所有元素累加
cumsum引數有:dtype,axis
a = np.array([[1,2,3], [4,5,6]])
print np.cumsum(a)
#輸出的結果:
# array([ 1, 3, 6, 10, 15, 21]) 它是上面的元素累加前一個值的結果
print np.cumsum(a, dtype=float)
#輸出的結果:
# [ 1. 3. 6. 10. 15. 21.]
print np.cumsum(a,axis=0) #每一列累加前一個值(1+4,2+5,3+6)
#輸出結果:
# [[1 2 3]
# [5 7 9]]
print np.cumsum(a,axis=1) #每一行累加前一個值[1,1+2,1+2+3],[4,4+5,4+5+6]
#輸出結果:
# [[ 1 3 6]
# [ 4 9 15]]