6. Function (60%)
函式,就跟國高中學的意思是一樣的,z = f(x, y) = x^2 + y^2,就是把常用的運算邏輯寫成一個有輸入和輸出的區塊,日後只要把值代入輸入,就會自動產生輸出,增加了程式碼的可重複使用性。Python這類程式語言已經有很多內建或者別人幫忙寫好的第三方函式,例如max(alist)
、sorted(alist)
等,但我個人會把一些我經常要用到、重複測試的邏輯區塊寫成函式以重複利用。例如在TM01. Term frequency 中,我們便把斷詞、篩去停用詞的各種不同的方法寫成函式,來比較其結果。
定義與使用函式
Python定義函式的語法如下,可以看見用def
作為關鍵字清楚地定義。return
後面相當於要傳回的值,例如上面的運算式x^2 + y^2
便會把運算的結果傳回函式的使用者。
關於傳回值,有些函式只是把內容列印出來,並沒有任何回傳值。有些函式會定義多個傳回值,且每個傳回值的資料型態都可以不同。
要使用函式的時候,要注意輸入的參數數量和型態以及輸出的參數數量。如果函式定義了兩個輸入,那就要給兩個變數,且資料型態要相同。有幾個傳回值,就要用幾個變數去接。在使用的時候,如果給錯輸入或輸出的數量,通常會產生Error。
# Define a function
def FUNCTION_NAME(INPUT1, INPUT2):
# Add member variable here
# Add some code here
return OUTPUT1, OUTPUT2
# Call the function
a, b = FUNCTION_NAME(c, d)
定義常用函式
通常我在寫Python的時候常常會自己定義一些函式當作我的小工具,並把他收在一個資料夾裡,等待日後使用的時候便可以把它叫進來用。
空值清理NaN and Null
要先注意到NaN
和Null
的定義不太一樣,NaN
多出現在number array的空值,Null
則是Python一般泛指的空值。Null
可以用if a is Null
來偵測, 但NaN
沒有辦法用這樣的方法來偵測。這邊有對NaN
和Null
的說明。
None vs NaN None and NaN sound similar, look similar but are actually quite different. None is a Python internal type which can be considered as the equivalent of NULL. The None keyword is used to define a null value, or no value at all. None is not the same as 0, False, or an empty string. It is a datatype of its own (NoneType) and only None can be … None. While missing values are NaN in numerical arrays, they are None in object arrays. It is best to check for None by using foo is None instead of foo == None which brings us back to our previous issue with the peculiar results I found in my NaN operations. https://towardsdatascience.com/navigating-the-hell-of-nans-in-python-71b12558895b
而偵測NaN的手法更是人人不同,如果是在Pandas中可以用pd.isnull(df1)
來偵測,或者自行查詢以下說明看要如何偵測NaN https://stackoverflow.com/questions/944700/how-can-i-check-for-nan-values。在這邊我們就舉其中一個例子來當作我們自己寫的函式。
def isnan(value):
try:
import math
return math.isnan(float(value))
except:
return False
產生顏色
視覺化時會經常需要把多個0至1間的值,把它轉到指定的兩個顏色之間的漸層顏色。以下函式的特色是10進位整數直接在印出的時候用16進位印出,即能達到要求。底下的程式碼這會產生一個綠到藍的漸層。
def gradient_green_blue(fnum):
r = 255-int(fnum*255)
b = int(fnum*255)
hex = "#%02x%02x%02x" % (0, r, b)
return hex
<函式練習01> Generating color list
我希望寫一個產生多個顏色的函式,但這次的輸入不要是上面0到1間的值,而是一個n。我要我的傳回值是一個List,如果n
等於8的話,該函式就要傳回8個漸層顏色的List給我、如果n的話就要傳回n
個。
<函式練習02> Advanced: Generating color list by specifying colors
接續函式01的練習,我希望寫一個產生多個顏色的函式,但這次的輸入不僅要有n,還要輸入漸層兩端的極端顏色,也就是說,這個函式可以讓使用者挑說我要從顏色A到顏色B(例如#334466或#AB3824),取n個顏色,所以一共會有三個輸入,輸出則與上題相同。嚴格上來說,這題不是在問函式,而是在考你會不會把16進位的顏色轉為0到255間的整數。
請把函式名稱和<函式練習01>的名稱取為一樣。日後,你給他三個輸入,他就會執行函式練習02這個,你給他一個輸入,就會執行函式練習01那個,這種同名函式會根據輸入參數數量和型態來判斷到底要執行哪一個的設計稱為「多型(polymorphism)」。
Polymorphism reference: https://overiq.com/python-101/inheritance-and-polymorphism-in-python/
數學函式
以下為計算標準差、變異數的函式寫法
import math
def mean(data):
if iter(data) is data:
data = list(data)
n = len(data)
if n < 1:
raise StatisticsError('mean requires at least one data point')
return float(sum(data))/n
def _ss(data, c=None):
"""Return sum of square deviations of sequence data.
"""
if c is None:
c = mean(data)
ss = sum((x-c)**2 for x in data)
# The following sum should mathematically equal zero, but due to rounding
# error may not.
ss -= sum((x-c) for x in data)**2/len(data)
assert not ss < 0, 'negative sum of square deviations: %f' % ss
return ss
def variance(data, xbar=None):
if iter(data) is data:
data = list(data)
n = len(data)
if n < 2:
raise StatisticsError('variance requires at least two data points')
ss = _ss(data, xbar)
return ss/(n-1)
def stdev(data, xbar=None):
"""Return the square root of the sample variance.
"""
var = variance(data, xbar)
try:
return var.sqrt()
except AttributeError:
return math.sqrt(var)
Last updated