1. 程式人生 > >python資料處理程式碼總結

python資料處理程式碼總結

一 numpy

簡介
nump用來是陣列和向量計算,是高效能科學計算和資料分析的基礎包。
ndarry:是一個具有向量運算和複雜廣播能力的快速且節省空間的多維陣列。
主要功能:資料整理和清理,子集構造和過濾,轉換等快速的向量化陣列運算;陣列演算法,如排序,唯一化,集合運算等。

(一).生成ndarry物件

ndarry:多維陣列物件,是快速靈活的資料集容器。

import numpy as np
1.a = np.array([1,2,3])/ np.asarray() #可傳入list,tuple,陣列或其他序列型別
print(a) #[1 2 3]
2.np.zero()
3.np.ones()
4.np.arange()
5.np.linspace(start,end,num)  #start~end等間隔產生num個數的序列
a = np.linspace(1,5,3)
print(a)   #[1. 3. 5.]
6.numpy.random(隨機抽樣)


有一個點需要強調:(2,)與(2,1)的區別
[1,2]的shape值(2,),意思是一維陣列,陣列中有2個元素。

[[1],[2]]的shape值是(2,1),意思是一個二維陣列,每行有1個元素。

[[1,2]]的shape值是(1,2),意思是一個二維陣列,每行有2個元素。

a=np.array([1,2,3])
b=np.array([[1],[2],[3]])
print(a.shape)
print(b.shape)

#結果:
(3,)
(3, 1)

更多詳見部落格


np.random.rand()#返回[0,1)的均勻分佈的隨機樣本
np.random.randn()#回一個樣本,具有標準正態分佈
numpy.random.randint(low, high=None, size=None, dtype='l')#小於low的size個整數


np.random.seed()

numpy.random.seed()是個很有意思的方法,接下來使用random()或者rand()方法所生成的隨機數序列都是相同的(僅限使用一次random()或者rand()方法,第二次以及更多次仍然是隨機的數字)

(1)外面
num = 1
np.random.seed(5)
while(num<5):
    print(np.random.random())
    num+=1
    
#結果:
0.22199317109
0.870732306177
0.206719155339
0.918610907938
(2)裡面
from __future__ import print_function
num = 1
while(num<5):
    np.random.seed(5)
    print(np.random.random(),'\t',end='')
    num+=1
#結果:
0.22199317109 	0.22199317109 	0.22199317109 	0.22199317109 	

(二).reshape+transpose

rehsape(a, newshape, order=‘C’)一個引數為-1時,那麼reshape函式會根據另一個引數的維度計算出陣列的另外一個shape屬性值。order('C’和’F’選項不考慮底層陣列的記憶體佈局,而只是參考索引的順序)

a=np.arange(12)
#b=np.reshape(a,(2,2,3)) #等價
b=a.reshape(2,2,3)
print(b)

#result:
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]

.transpose(a,axes=None):反轉的輸入陣列的維度,當給定這個引數時,按照axes引數所定的值進行陣列變換。

a=np.arange(10).reshape(2,5)
b=np.transpose(a)
print(b.shape,a.shape)

#結果:
((5, 2), (2, 5))

(三). np.multiply()/*和np.dot

*/np.multiply():對應元素相乘

b=np.arange(6).reshape(2,3)
copy_b=b.copy()
a=np.arange(6).reshape(3,2)
print('*:')
print(copy_b*b)
print('multiply:')
print(np.multiply(copy_b,b))
print('dot:')
print(np.dot(b,a))

#結果:
*:
[[ 0  1  4]
 [ 9 16 25]]
multiply:
[[ 0  1  4]
 [ 9 16 25]]
dot:
[[10 13]
 [28 40]]
 
 
 a=np.arange(4).reshape(2,2)
b=np.arange(8).reshape(2,2,2)
a2=np.arange(8).reshape(1,2,2,2)
b2=np.arange(16).reshape(2,2,2,2)
print(a*b)
print(a2*b2)

#結果:
a*b:
[[[ 0  1]
  [ 4  9]]

 [[ 0  5]
  [12 21]]]
  
a2*b2: 
[[[[  0   1]
   [  4   9]]

  [[ 16  25]
   [ 36  49]]]


 [[[  0   9]
   [ 20  33]]

  [[ 48  65]
   [ 84 105]]]]
Xn維*Ym維:n>1
n=m:確保2~n維與2~m維數相同,X第一維為1
n<m:確保X維數與Y的m-n+1~m維對應相等,2x2 3x2x2 可以

(四). np.sum,np.prod,np.pad

np.sum: axis表示在哪一維度求和


b=np.arange(24).reshape(2,2,3,2)
print('b----')
print(b)
print('axis=0----')
print(np.sum(b,axis=0))
print('axis=1----')
print(np.sum(b,axis=1)) 
print('axis=2----')
print(np.sum(b,axis=2))


#結果:
b---- 2x2x3x2
[[[[ 0  1]
   [ 2  3]
   [ 4  5]]

  [[ 6  7]
   [ 8  9]
   [10 11]]]
 [[[12 13]
   [14 15]
   [16 17]]
  [[18 19]
   [20 21]
   [22 23]]]]
  
axis=0----3x3x2
[[[12 14]
  [16 18]
  [20 22]]
  
 [[24 26]
  [28 30]
  [32 34]]]
  
axis=1----2x3x2
[[[ 6  8]
  [10 12]
  [14 16]]

 [[30 32]
  [34 36]
  [38 40]]]
  
axis=2----2x2x2
[[[ 6  9]
  [24 27]]

 [[42 45]
  [60 63]]]
  
  
x_shape = (2, 3, 4, 4)
num=np.prod(x_shape) #對應元素求乘積
num

#96

np.pad
在哪個維度上填充數值,預設填充0

更多見部落格

arr3D=np.arange(8).reshape(2,2,2)
print('constant:  \n' + str(np.pad(arr3D, ((0, 0), (1, 1), (2, 2)), 'constant')))
#(2,2)/(2,):表示前面兩個後面兩個
print('constant2:  \n' + str(np.pad(arr3D, ((1, ), (2, ), (2, )), 'constant')))

#結果:
constant:  
[[[0 0 0 0 0 0]
  [0 0 0 1 0 0]
  [0 0 2 3 0 0]
  [0 0 0 0 0 0]]

 [[0 0 0 0 0 0]
  [0 0 4 5 0 0]
  [0 0 6 7 0 0]
  [0 0 0 0 0 0]]]
constant2:  
[[[0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]]

 [[0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 1 0 0]
  [0 0 2 3 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]]

 [[0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 4 5 0 0]
  [0 0 6 7 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]]

 [[0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]
  [0 0 0 0 0 0]]]

五np.argsort

numpy.argsort(a, axis=-1, kind=’quicksort’, order=None)
kind : {‘quicksort’, ‘mergesort’, ‘heapsort’}, optional
Sorting algorithm.

axis=0:按列排序
axis=1:按行排序
axis=-1:預設按最後一維度,即按行排序
功能: 將矩陣a按照axis排序,並返回排序後的下標
引數: a:輸入矩陣, axis:需要排序的維度
返回值: 輸出排序後的下標

a = np.array([[2,32,121],[32,12,23]])
print(a)
b=np.argsort(a,axis=1)
b2=np.argsort(-a)
b3=np.argsort(a,axis=-1)
print(b)
print(b2)
print(b3)

#結果:
[[  2  32 121]
 [ 32  12  23]]
[[0 1 2]
 [1 2 0]]
[[2 1 0]
 [0 2 1]]
[[0 1 2]
 [1 2 0]]
 
a=np.arange(12).reshape(2,3,2)
print(a)
print('________')
print(np.sum(a,axis=0)) #第一維:3x2
print('________')
print(np.sum(a,axis=1)) #第二維:按列加2x2
print('________')
print(np.sum(a,axis=2)) #第三維:2x3按行加                     
#結果:
[[[ 0  1]
  [ 2  3]
  [ 4  5]]

 [[ 6  7]
  [ 8  9]
  [10 11]]]
________
[[ 6  8]
 [10 12]
 [14 16]]
________
[[ 6  9]
 [24 27]]
________
[[ 1  5  9]
 [13 17 21]]

六. numpy.bincount

bincount(x, weights=None, minlength=0)
bin是x中最大值max,返回從索引0~max的計數。
weights引數被指定,那麼x會被它加權,也就是說,如果值n發現在位置i,那麼out[n] += weight[i]而不是out[n] += 1.因此,我們weights的大小必須與x相同,否則報錯。
最後,我們來看一下minlength這個引數。文件說,如果minlength被指定,那麼輸出陣列中bin的數量至少為它指定的數(如果必要的話,bin的數量會更大,這取決於x)即bin>=minlength

例項就不舉了這篇部落格總結的很好

七. stack(),hstack(),vstack()

stack(arrays, axis=0):它就是對arrays裡面的每個元素(可能是個列表,元組,或者是個numpy的陣列)變成numpy的陣列後,再對每個元素增加一維(至於維度加在哪裡,是靠axis控制的)

hstack:它其實就是水平(按列順序)把陣列給堆疊起來,vstack()函式正好和它相反。
vstack:它是垂直(按照行順序)的把陣列給堆疊起來。
部落格

a=([1,2,3],3,1)
b=[4,5,6]
print(np.hstack((a,b)))
print(np.vstack((a,b)))

#結果:
[list([1, 2, 3]) 3 1 4 5 6]
[[list([1, 2, 3]) 3 1]
 [4 5 6]]

八. np.squeeze()

從陣列的形狀中刪除單維條目,即把shape中為1的維度去掉

x = np.array([[[0], [1], [2]]])
print(x.shape)
print(np.squeeze(x).shape)

九. numpy的broadcasting性質

A=np.array([1,2])
B=np.array([[3],[4]])
print(A.shape)
print(B.shape)
print((A+B).shape)
print(A+B)

#結果:
(2,)
(2, 1)
(2, 2)
[[4 5]
 [5 6]]

二 資料結構

(一)序列(sequence)

每個元素都分一個數字(位置,索引:從0開始,最後一個是-1)
6種內建序列:列表(list),元組(tuple),字串,Unicode字串,buffer物件

dict和set

dict是同java hashMap一樣的Key-value資料型別,{}表示。
散列表是無序的,其順序是被新增的次序而定的,且新增元素可能會改變集合原有次序。

1.初始化
、# dic={}
# dic['a']=1  #增加元素
dic={'a':1}
print(dic)

#result:
{'a': 1}
2.遍歷
dic={'a':1,'b':2} 
print(dic.items()) # 一列表形式返回可遍歷的(K,V)元組list
#結果:[('a', 1), ('b', 2)]
print(dic.keys())  #dic.values()返回值
# 結果:['a', 'b']
3.刪除
del dic['b']
print(dic.keys())
#結果:['a']

python3中,keys(),items(),values()返回的都是字典檢視,python2返回的是列表。檢視具有動態特徵,可以實時反饋字典變化。

set和dict類似,也是一組key的集合,但不儲存value。由於key不能重複,所以,在set中,沒有重複的key

1.list內建方法
list和tuple

tuple元組,同list,使用(),元素一旦初始化就不可修改,tuple內元素可以為list等其他序列資料型別,其內容可變。
str和tuple加上bytes是不變物件/序列,而list是可變物件

#前python <=>後java對比
1.append()<=>add()
2.len()<=>.size
3.+/.extend()<=>.addAll()
list.append(object) 向列表中新增一個物件object
list.extend(sequence) 把一個序列seq的內容新增到列表中

a=range(5)
new=range(6,10)
a.append(new)
print(a)

#結果:
[0, 1, 2, 3, 4, [5,6, 7, 8, 9]]

a=range(5)
new=range(5,10)
a.extend(new)
print(a)

#結果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4.in<=>.contains()
5.list.count(val)
6..remove(val)
7.pop(index) #刪除索引,default:最後一個
2.list切片(slice)
":" 表示該維度全部資料
b=np.array([1,2,3])
a=b[None,:,None,None]
a2=(b)[None,:,None,None]#與上式等價
print(a)
print(a.shape)
print(a2.shape)

# None是一個特殊的常量,有自己的資料型別NoneType,和False不同,不是0,不是空字串,和任何其他的資料型別比較永遠返回False
#可以將None複製給任何變數,但是你不能建立其他NoneType物件 

#結果:
[[[[1]]

  [[2]]

  [[3]]]]
(1, 3, 1, 1)
(1, 3, 1, 1)


a=np.arange(12).reshape(3,4)
print(a,'\n')
print(a[:,2:],'\n')
print(a[:,:-2:2])

在每一維度中 m:n表示從下標[m,n)的元素
m:n:d 表示從m開始每隔d取一元素
#結果:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]] 

[[ 2  3]
 [ 6  7]
 [10 11]] 

[[0]
 [4]
 [8]]
3. enumerate

在迴圈體內訪問每個元素的指標

 animals = ['cat', 'dog', 'monkey']
   for idx, animal in enumerate(animals):
       print '#%d: %s' % (idx + 1, animal)
#結果:
1: cat
2: dog
3: monkey

4 sort/sorted

sort 與 sorted 區別:

sort 是應用在 list 上的方法,sorted 可以對所有可迭代的物件進行排序操作。

list 的 sort 方法返回的是對已經存在的列表進行操作,無返回值,而內建函式 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。

sorted(iterable[, cmp[, key[, reverse]]])
iterable -- 可迭代物件。
cmp -- 比較的函式,這個具有兩個引數,引數的值都是從可迭代物件中取出,此函式必須遵守的規則為,大於則返回1,小於則返回-1,等於則返回0。
key -- 主要是用來進行比較的元素,只有一個引數,具體的函式的引數就是取自於可迭代物件中,指定可迭代物件中的一個元素來進行排序。
reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(預設)。


L=[('b',2),('a',1),('c',3),('d',4)]
print(sorted(L, cmp=lambda x,y:cmp(x[1],y[1])))   # 利用cmp函式

print(sorted(L, key=lambda x:x[1]))               # 利用key

 
 
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print(sorted(students, key=lambda s: s[2]))          # 按年齡排序

 
print(sorted(students, key=lambda s: s[2], reverse=True))       # 按降序


#結果:
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
4.列表生成式/列表推導

指把一個序列或其他可迭代型別中的元素過濾或加工,然後再新建一個列表。(比filter/map等lambda表示式更簡潔)

symbols='$*^#@%&'
ascii=[ord(s) for s in symbols if ord(s)>40]#if ord(s)>127
ascii_lambda=list(filter(lambda c: c > 40, map(ord, symbols)))
print(ascii)
print(ascii_lambda)

#結果
[36, 42, 94, 35, 64, 37, 38]
[36, 42, 94, 35, 64, 37, 38]


colors=['black','red']
sizes=['S','M','L']
tshirts=[(color, size) for color in colors for size in sizes]
print(tshirts)

#結果:
[('black', 'S'), ('black', 'M'), ('black', 'L'), ('red', 'S'), ('red', 'M'), ('red', 'L')]

其他

一 format

format函式用於字串的格式化

1.通過關鍵字
print('{name1}今天{name2}'.format(name1='陳某某',name2='跑步'))#通過關鍵字
grade = {'name' : '陳某某', 'fenshu': '59'}
print('{name}電工考了{fenshu}'.format(**grade))#通過關鍵字,可用字典當關鍵字傳入值時,在字典前加**即可

#結果:
陳某某今天跑步
陳某某電工考了59

2.通過位置
print('{1}今天{0}'.format('跑步','陳某某'))#通過位置
print('{0}今天{1}'.format('跑步','拍視訊'))

#結果:
陳某某今天跑步
陳某某今天跑步

3.精度
print('{:.1f}'.format(4.234324525254))
print('{:.4f}'.format(4.1))
print('{:,}'.format(100000000))
print('{:,}'.format(235445.234235))

#結果:
4.2
4.1000
100,000,000
235,445.234235
生成器

如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?這樣就不必建立完整的list,從而節省大量的空間。在Python中,這種一邊迴圈一邊計算的機制,稱為生成器:generator。

要建立一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就建立了一個generator:
如果要一個一個打印出來,可以通過next()函式獲得generator的下一個返回值:generator的函式,在每次呼叫next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。在for迴圈的過程中不斷計算出下一個元素,並在適當的條件結束for迴圈。對於函式改成的generator來說,遇到return語句或者執行到函式體最後一行語句,就是結束generator的指令,for迴圈隨之結束。

1.
g = (x*x for x in range(10))
print(g)
for x in g:
    print(x)
    
#結果:
<generator object <genexpr> at 0x1050e8cd0>
0
1
4
9
16
25
36
49
64
81
 
2. generator函式 
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
   
f = fib(6)
for x in f:
    print(x)


#結果:
1
1
2
3
5
8


簡單地講,yield 的作用就是把一個函式變成一個 generator,帶有 yield 的函式不再是一個普通函式,Python 直譯器會將其視為一個 generator

不用generator:
class Fab(object):
    def __init__(self,max):
        self.max = max
        self.n, self.a, self.b = 0,0,1
    
    def __iter__(self):
        return self
    def next(self):
        if self.n < self.max:
            r = self.b
            self.a,self.b = self.b, self.a + self.b
            self.n = self.n + 1
            return r
        raise StopIteration()

for n in Fab(5):
    print(n)
    
#結果:
1
1
2
3
5

我們基本上從來不會用next()來獲取下一個返回值,而是直接使用for迴圈來迭代.

對於python2.7 不能包含return,否則報錯。

python3可以
用for迴圈呼叫generator時,發現拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
f = fib(6)
print(f)

g = fib(6)
while True:
    try:
        x = next(g)
        print('g:',x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break
        
#結果:
<generator object fib at 0x10ed0a2b0>
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done