Python資料分析 | (1)Python語法基礎
本篇部落格所有示例使用Jupyter NoteBook演示。
Python資料分析系列筆記基於:利用Python進行資料分析(第2版) 下載密碼:pelb
目錄
Python語法基礎
1.語言的語義
Python強調可讀性、簡潔和清晰。
- 語句塊使用縮排而不是大括號
#排序演算法的for迴圈
for x in array:
if x<pivot:
less.append(x)
else:
greater.append(x)
冒號標誌縮排程式碼塊開始,之後所有程式碼縮排量必須相同,直到程式碼塊結束。
建議使用四個空格或者tab進行程式碼縮排。
Python語句不需要用";"結尾,但它可以在同一行進行語句切分,不建議把多條語句放在一行:
a=5;b=6;c=7
- 萬物皆物件
Python中每個數字、字串、資料結構、函式、類、模組等,都被認為是Python物件。
每個物件都有型別和內部資料。
函式也可被當作物件使用。
- 註釋
單行註釋是一段用“#”開頭的文字,註釋可以載入程式碼後,也可以在程式碼前:
print("hello world!") #簡單輸出
#簡單輸出
print("hello world!")
也可以用“#”註釋掉不想執行的程式碼:
for i in range(5):
#i+=1
print(i)
2.函式和物件方法呼叫
用圓括號呼叫函式,傳遞0或多個引數,或把返回值賦給一個變數:
result=f(x,y,z)
g()
Python中的每個物件幾乎都有附加的函式(方法),呼叫形式一般為:
obj.some_method(x,y,z)
函式可以使用位置和關鍵詞引數:
result=f(x,y,z,d=5,e='foo')
3.變數和引數傳遞
Python中建立變數,相當於為等號右邊的部分建立了一個引用:
a=[1,2,3]
b=a #把a賦給b 在有些語言中只是值的複製 但在Python中2者是同一個物件
a.append(4)
b
賦值也叫繫結,把一個名字繫結給一個物件。
當把物件作為引數傳給函式時,新的區域性變數建立了對原始物件的引用而不是複製:
def append_element(some_list,element):
some_list.append(element)
data=[1,2,3]
append_element(data,4)
data
4.動態引用,強型別
和許多編譯語言(c,java)不同,Python的物件引用不包含附屬型別:
a=5
print(type(a))
a='foo'
print(type(a))
變數是特殊名稱空間中物件的名字,型別資訊和具體的值儲存在物件自身中。
Python是強型別化語言,即每個物件都有明確的型別,預設的轉換之發生在特定情況下:
'5'+5 #字串和數字不存在預設的型別轉換
a=2
b=2.5
print('a is {0},b is {1}'.format(type(a),type(b)))
b/a #int型別向上轉型為float 再運算 結果為float
知道物件型別很重要,最好讓函式能處理多種型別的輸入。
可以用isinstance檢查物件屬於什麼型別:
a=5
print(isinstance(a,int))
a=5;b=4.5
print(isinstance(a,(int,float))) #也可以檢查物件 是否在型別元組中
print(isinstance(b,(int,float)))
5.屬性和方法
Python的物件一般都有屬性(儲存在物件內部的Python物件)和方法(物件的方法可訪問物件內部資料)。
呼叫形式:
obj.attribute_name.
obj.some_method(x,y,z)
a='foo'
a. #檢視物件a的屬性和方法 tab
也可以通過getattr函式,通過名字訪問物件的屬性和方法:
getattr(a,'split')
6.鴨子型別
我們可能不關心物件的型別,只關心它是否有某些屬性或方法,成為鴨子型別。
比如:驗證一個物件是否可迭代,即它是否有一個__iter__的方法,可使用iter函式判斷是否可迭代:
def isiterable(obj):
try:
iter(obj)
return True #物件可以迭代
except:
return False #不可以迭代
#字串物件和大多數Pyhton集合物件 都是可迭代的
print(isiterable('a string'))
print(isiterable([1,2,3]))
print(isiterable(5))
一般用這個功能編寫可以接收多種輸入型別的函式。
比如:編寫一個函式可以接受任意型別的序列(列表,陣列,元組等)或迭代器,可以先檢驗物件是否是列表,不是轉換為列表:
if not is instance(x, list) and isiterable(x):
x=list(x)
7.引入
Python中模組就是包含Python程式碼的檔案,有.py的副檔名。
如:以下這個模組
#some_module.py
PI=3.14
def f(x):
return x+2
def g(a,b):
return a+b
在同目錄下另一個檔案訪問some_module.py中定義的變數和函式:
import some_module
res=some_module.f(5)
pi=some_module.PI
或者:
from some_module import f,g,PI
res=g(5,PI)
使用as可以給引入更名,是名稱更簡潔:
import some_module as sm
form some_module import PI as pi,g as gf
r1=sm.f(pi)
r2=gf(6,pi)
8.二元運算子和比較運算子
print(5-7)
print(12+22.5)
print(2>=5)
用is/is not可以判斷兩個引用是否指向同一個物件:
a=[1,2,3]
b=a
print(a is b)
c=list(a) #list()建立一個新的列表物件 即只是值的複製
print(a is c)
print(a is not c)
is比較和==比較是不同的:
print(a is c) #比較兩個引用是否指向同一個物件
print(a==c) #比較兩個引用內部的數值是否相等
is/is not常用來判斷一個變數是否為None:
a=None
a is None
9.可變與不可變物件
Python中大多數物件如列表、陣列、字典,自定義的類都是可變的,即這些物件或包含的值可以被修改:
a_list=[2,3,'foo',(3,4)]
a_list[3]=[3,4]
a_list
典型的字串和元組是不可變的:
a_tuple(2,3,(4,5))
a_tuple[1]='foo' #報錯
10.標量型別
Python用於處理數值資料、字串、布林值和日期時間的內建型別,叫單值/標量型別。
11.數值型別
主要型別int和float。
與其他語言不同,Python的int可以儲存任意大的數:
ival=1234567
ival**6
float型別都是雙精度(64位)的值:
fval=1.23
fval1=5.76e-5 #科學計數法
不能得到整數的除法得到浮點數:
print(3/2)
print(3//2) #地板除法 c語言中的除法 向下取整
12.字串
可以用''或""包括,有換行符的字串用三引號'''或"""包括:
a='string s1'
b="string s2"
c="""
this is a longer string that
spans multiple lines
"""
c中有四行文字,統計c中的換行符:
c="""
This is a longer string that
spans multiple lines
"""
c.count('\n')
Python的字串不可變:
a='this is a string'
a[10]='f' #報錯
a='this is a string'
b=a.replace('string','longer string')
print(b)
print(a) #a的值並沒有變
許多Python物件可以用str()轉化為字串:
a=5.6
s=str(a)
s
字串是字元的序列,可以像其他序列,如列表、元組等一樣處理:
s='python'
print(list(s))
print(s[0]) #取值
print(s[:3]) #切片
反斜槓可以用來轉義:
#輸出帶有反斜槓的字串
s='12\\34'
print(s)
s=r'this\is\a\string' #如果一個字串有很多\,但沒有一個是特殊字元 可以加一個r 表示就是字串自身
s
字串合併:
a='first string! '
b='second string'
a+b
字串物件的format方法:
template='{0:.2f}{1:s} are worth USDollar${2:d}'.format(4.5560,'AP',1)
template
13.位元組和Unicode
將unicode字串編碼成utf-8位元組格式
val='español'
print(val)
val_utf8=val.encode('utf-8') #把unicode字串 編碼成utf-8位元組文字 encode編碼
print(val_utf8)
print(type(val_utf8))
val_utf8.decode('utf-8') #decode 解碼 將位元組文字解碼成字串
將unicode字串編碼成其他位元組格式:
print(val.encode('utf-16'))
print(val.encode('utf-16le'))
字串前加b表示位元組文字:
bytes_val = b'this is bytes' #位元組文字
print(bytes_val)
decoded=bytes_val.decode('utf-8') #解碼成unicode string
print(decoded)
14.布林值
布林值只有True和False。
條件表示式和比較用True和False判斷。
布林值可以與and or結合使用
True and True,False or False
15.型別轉換
str、float、int、bool這些函式可用來轉換型別:
s='3.14'
fval=float(s)
print(type(fval))
print(int(fval))
print(bool(fval)) #非0True
bool(0) #0False
16.None
Python空值型別,一個函式如果沒有明確的返回值,則預設返回None:
a=None
print(a is None)
b=5
print(b is not None)
None經常作為函式的預設引數:
def add_maybe_multiply(a,b,c=None):
res=a+b
if c is not None:
res*=c
return res
None是唯一的NoneType例項:
17.日期和時間
Python內建的datetime模組提供了datetime、date和time型別。
datetime是date和time的結合,最常使用:
from datetime import datetime,date,time
dt=datetime(2018,11,10,14,20,31) #建立一個時間和日期的例項
print(dt)
print(dt.day) #取天數
print(dt.hour) #取小時數
print(dt.date()) #取出date物件
print(dt.time()) #取出time物件
print(dt.strftime("%m/%d/%Y %H:%M")) #日期轉換成字串
print(datetime.strptime('20091031','%Y%m%d')) #字串轉換日期
格式化命令:
聚類或對時間序列進行分組時,替換datetime的time欄位很有用,如用0替換秒和分:
dt.replace(minute=0,second=0) #datetime型別不可變 dt是不變的 此時會返回一個新的物件
兩個datetime物件做差,產生datetime.timedelta物件:
dt2=datetime(2018,12,11,11,11)
delta=dt2-dt
print(delta)
print(type(delta))
print(dt2)
print(dt+delta)
18.控制流
- if、elif和else
if x<0:
print('negative')
一個if後可跟多個elif,所有條件都是False,還可以新增一個else:
if x<0:
print('negative')
elif x==0:
print('zero')
elif 0<x<5: #可以連寫
print('0<x<5')
else:
print('>=5')
某個條件為True,後面elif就不會執行。
使用and和or時,複合條件語句從左至右執行。
短路效應:如果前面一個條件已經滿足,後一個就不會再執行判斷了:
a=5;b=7
c=8;d=4
if a<b or c>d: #c>d不會執行 a<b為true 整個條件表示式的值已經確定了
print('yes')
比較式可以連寫:
- for迴圈
for迴圈在一個集合(列表、元組等)或i 個迭代器中進行迭代:
for value in collection:
do sth
continue可以跳過for迴圈剩下的部分,進入下一次迴圈:
sequence = [1, 2, None, 4, None, 5]
total = 0
for value in sequence:
if value is None:
continue
total += value
total
break可以跳出for迴圈:
sequence = [1, 2, 0, 4, 6, 5, 2, 1]
total_until_5 = 0
for value in sequence:
if value == 5:
break
total_until_5 += value
break只能中斷最內層的for迴圈,其餘for迴圈仍會執行:
for i in range(4):
for j in range(4):
if j>i:
break
print((i,j))
如果集合或迭代器中的元素是元組或列表,可以用for把它拆分為變數:
for a,b,c in iterator:
do sth
- While迴圈
指定條件和程式碼塊,只有當條件為false,或使用break時,才會退出:
x = 256
total = 0
while x > 0:
if total > 500:
break
total += x
x = x // 2
- pass
非操作語句,程式碼塊不需要任何動作時可以使用:
if x<0:
print('negative')
elif x==0:
pass
else
print('positive')
- range
返回一個迭代器:
print(range(10)) #均勻分佈的整數序列
print(list(range(10)))
print(list(range(0,20,2))) #三個引數 起點 終點(不包括) 步長(預設為1)
print(list(range(5,0,-1))) #負步長 相反方向
range常用於用序號迭代序列:
seq=[1,2,3,4]
for i in range(len(seq)):
print(seq[i])
for i in seq:
print(i)
sum = 0
for i in range(100000):
# % is the modulo operator
if i % 3 == 0 or i % 5 == 0:
sum += i
19.三元表示式
把if-else語句放在一行中 :
value = true-expr if condition else false-expr
true-expr和false-expr可以是任何Python語句。
等價於:
if condition:
value = true-expr
else:
value = false-expr
x=5
"negative" if x<0 else 'positive'
三元表示式可以壓縮程式碼,但是降低了可讀性。