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

要先注意到NaNNull的定義不太一樣,NaN多出現在number array的空值,Null則是Python一般泛指的空值。Null可以用if a is Null來偵測, 但NaN沒有辦法用這樣的方法來偵測。這邊有對NaNNull的說明。

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

<函式練習02> Advanced: Generating color list by specifying colors

數學函式

以下為計算標準差、變異數的函式寫法

myStat.py
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