All Revision Notes

COM6001 Computing with Big Data · Week 8

Text Cleaning & Feature Scaling

COM6001 · Week 8 · Source: Lecture08_Text_Cleaning_Scaling.pdf(Jupyter notebook export, 18 pages)· Lecturer: Dr. Aileen Hou

Contents · 12 sections

🎯 本講重點 (Learning outcomes)

  • 用 string accessor .str 對成個 column 做 string methods:lower()/upper()、strip()、replace()、len()、contains()、startswith()、slicing .str[-3:]。
  • 用 Boolean mask 組合多個 text 條件(&、~)去 filter / count rows(NYC taxi 例子)。
  • Regular expressions (Regex):. \d \w \s * + ? ^ $;Python re.findall()、re.sub();pandas .str.extract()、.str.contains(pattern)(HK property address 例子)。
  • Feature scaling:點解要 scale(K-means distance 例子);StandardScaler、MinMaxScaler、RobustScaler 嘅公式、對 outliers 嘅敏感度、output range 同幾時用邊個。

⭐ 考試必溫 Top-5

  1. 三條 scaling 公式:Standard x′=x−meanstdx' = \frac{x - \text{mean}}{\text{std}};Min-max x′=x−min⁡max⁡−min⁡x' = \frac{x - \min}{\max - \min};Robust x′=x−Q2Q3−Q1x' = \frac{x - Q_2}{Q_3 - Q_1}。
  2. Outlier 敏感度:MinMax 最敏感 > Standard 中等 > Robust 最唔敏感;只有 MinMax 有固定 range [0, 1]。
  3. Rules of thumb:無強 outliers / distance-based 或 assume normality → Standard;要固定 interval / activation function input → MinMax;好多 outliers / heavy tails → Robust。
  4. Scaler 只可以 fit 喺 training data,validation/test 用已 fit 嘅 scaler 去 transform(避免 data leakage)。
  5. .str accessor + string method 處理成個 column;regex 基本符號同 str.extract()(capture group ( ))/str.contains() 用法。
📄 講義範圍

封面寫住「COM 6001 Lecture 07」,但檔名同內容係 Lecture 08。開頭 outline 列咗 Review of Feature Transformation、Cleaning texts、Scaling、Mapping new values、Applying functions,不過今份 notebook 實際只有 Cleaning texts 同 Scaling 兩部分有內容;最尾 summary 亦重溫 Week 7 嘅 datetime、encoding、binning。

1. Review: Feature Transformation(Week 7 回顧)

Outline 一開始重溫上堂嘅 categorical → numerical 轉換:

  • Nominal data(無次序,例如顏色)→ one-hot encoding:pd.get_dummies(df, prefix=...)。
  • Ordinal data(有次序,例如 Low/Mid/High)→ ordinal encoder:OrdinalEncoder(categories=[[...]])。

Summary slide 仲提到:datetime 用 .dt accessor;binning 要分清 cut()(equal-width / 自訂 edges)同 qcut()(equal-sized / quantile-based)。詳細內容睇 Week 7。

2. Data preparation:NYC Federal Taxi dataset

import pandas as pd
dir_path = './Datasets/week_8/'
nyc = pd.read_csv(dir_path + 'nyc_federal_taxi.csv')
nyc.info()     # 267 rows × 7 columns,全部 dtype = object
nyc.head(3)

7 個 columns:Date、Time、PU_Address(pick-up)、DO_Address(drop-off)、Routing Details、PU_Address.1、Status(例如 Cancelled / Arrived / Assigned)。全部都係 object(string),所以呢份 data 正正需要 text cleaning。

💡 直覺理解

PU_Address.1 呢個名係 pandas 自動加嘅:原 CSV 有兩個 column 都叫 PU_Address,read_csv 會將第二個改名做 PU_Address.1 避免重複。

3. Cleaning texts with string methods

Text data 通常由唔同 users / collectors、喺唔同 platforms 輸入,所以格式好少一致。Slides 列出常見問題同對應 method:

⭐ 考試重點:問題 → method
問題MethodSlides 例子
Upper/lower cases 唔統一.str.lower() / .str.upper()nyc['PU_Address'].str.lower()
White spaces(頭尾多咗空格).str.strip()nyc['PU_Address'] = nyc['PU_Address'].str.strip()
Abbreviations 唔統一.str.replace(old, new)nyc['PU_Address'].str.replace('ny;', 'new york;')
Fixed-length terms(zipcode、postcode、時間)長度檢查.str.len()nyc['Time'].str.len() → 全部應該係 8
Filter 含某 keyword 嘅 entries.str.contains('kw')nyc[nyc['PU_Address'].str.contains('airport')]
抽每格某一段 charactersslicing .str[a:b]nyc['PU_Address'].str[-3:]
開頭 / 結尾係某 sub-string.str.startswith() / .str.endswith()nyc[nyc['PU_Address'].str.startswith('best western')]

記住:一定要經 .str accessor,string method 先會 apply 到 每一個 cell(cell level)。

Observation 1 on the NYC Taxi Data

  • Cases 唔統一(有啲大楷、有啲細楷)。
  • 有啲 white spaces 肉眼唔易見,例如 head(10) 入面 line 3 同 line 6 尾有多餘空格。

證據:nyc['PU_Address'].str[-3:] 抽最後三個字元,大部分係 NY;、NJ;,但 row 2 出咗 Y;,因為尾有一個空格,最後三格變成「Y; 」。

nyc['PU_Address'] = nyc['PU_Address'].str.lower()   # 統一做細楷
nyc['PU_Address'] = nyc['PU_Address'].str.strip()   # 去頭尾空白
nyc['PU_Address'].str[-3:]                          # 而家全部係 'ny;' / 'nj;'

print("hello world\n")           # 會多印一行空行
print("hello world\n".strip())   # strip() 連 \n 都會去埋
print("   hello world   ".strip())  # 'hello world'
⚠️ 常見錯誤
  • String methods 唔會 in-place 修改:nyc['PU_Address'].str.lower() 只會回傳新 Series,一定要 assign 返:nyc['PU_Address'] = ...。
  • strip() 只去 頭尾 嘅 whitespace(space、\n、\t),中間嘅多個空格唔會處理 → 要用 regex re.sub(r'\s+', ' ', text)(見 Section 4)。
  • contains() default 係 case-sensitive:lower 咗 PU_Address 之後要搵 'airport';但 DO_Address 冇 lower,所以 Task 4 要搵 'Flushing'(大楷 F)。

Tasks(課堂練習)

Exam 呢幾題係典型「寫一行 pandas code」題型:

# Task 1:刪走每個地址尾嘅 state field(空格 + 州名縮寫 + ';'),例如 " ny;"
nyc['PU_Address'] = nyc['PU_Address'].str[:-4]    # 去最後 4 個字元

# Task 2:有幾多條 route 由 airport 出發?
nyc[nyc['PU_Address'].str.contains('airport')].shape[0]     # 29

# Task 3:PU_Address 以 'best western' 開頭,而且去 airport(DO_Address 含 airport)
nyc[(nyc['PU_Address'].str.startswith('best western'))
    & (nyc['DO_Address'].str.contains('Airport'))]          # 1 row(index 102)

# Task 4:狀態係 'Arrived',而且 drop-off 係 Flushing
nyc[nyc['DO_Address'].str.contains('Flushing') & (nyc['Status'] == 'Arrived')]   # 2 rows
📄 Code 被截斷

PDF 入面 Task 3 嗰行 code 喺 & (nyc['DO_Addre… 被截斷,上面 contains('Airport') 係按題目意思補返(DO_Address 冇 lower,原文寫 "John F Kennedy International Airport");請對照原 notebook 第 5 頁。

⚠️ 易混淆

Task 1 嘅 .str[:-4] 假設每格尾都係「空格 + 兩個字母 + ;」。Output 第 262 行(907 59 st., bk ny; st: w66 st./broadway, ny)顯示有啲地址有兩段,只會刪最後一段——固定長度 slicing 對格式唔一致嘅 data 唔夠 robust,呢個正正係引入 regex 嘅原因。另外組合條件時每個條件要加括號,用 & / |,唔可以用 and / or。

4. Introduction to Regular Expressions (Regex)

Regular expressions 係用嚟 match、search、manipulate text 嘅 patterns。Data science 用途:

  • Cleaning messy text data
  • Extracting specific information from strings
  • Validating data formats(emails、phone numbers 等)

Lecturer 特別提到:course project 好大機會遇到格式唔一致嘅 dataset,regex 可以有效處理。Python 用 re module:import re。

⭐ 考試重點:Basic syntax
PatternMeaningExample
.Any single charactera.c matches "abc", "a1c"
\dAny digit (0-9)\d\d\d matches "123"
\wAny word character (letters, digits, underscore)\w+ matches "hello"
\sAny whitespacea\sb matches "a b"
*Zero or more occurrencesab*c matches "ac", "abc", "abbc"
+One or more occurrencesab+c matches "abc", "abbc"(not "ac")
?Zero or one occurrencecolou?r matches "color" and "colour"
^Start of string^Hello:以 "Hello" 開頭
$End of stringworld$:以 "world" 結尾
💡 直覺理解:quantifier 只作用喺前一個字元

ab*c 嘅 * 只修飾 b,所以係「a、任意個 b(可以 0 個)、c」。* vs + 嘅分別就係「0 個得唔得」:ab*c match "ac",ab+c 唔 match。? 就係「可有可無」。

Using re module with Python

import re

# Example 1:搵晒所有數字(一個或多個連續 digits)
text = "Order #12345 was placed on 2026-10-19"
re.findall(r'\d+', text)          # ['12345', '2026', '10', '19']

# Example 2:抽 email address
text = "Contact us at info@example.com or support@test.org"
re.findall(r'[\w\.-]+@[\w\.-]+\.\w+', text)   # ['info@example.com', 'support@test.org']

# Example 3:將多個空格變一個
text = "This    are   many     spaces"
re.sub(r'\s+', ' ', text)          # 'This are many spaces'
  • re.findall(pattern, text):回傳所有 non-overlapping matches 嘅 list。
  • re.sub(pattern, repl, text):將所有 match 替換成 repl。
  • r'...'(raw string):令 \d 嘅 backslash 唔會俾 Python 當 escape character。
  • Email pattern 拆解:[\w\.-]+(一個或多個 word char / 點 / 減號)+ @ + domain [\w\.-]+ + \.(真正嘅點,要 escape)+ \w+(com / org)。[...] 係 character class:入面任何一個字元都 match。

Regex with pandas:HK property data

pandas 可以直接經 .str accessor 用 regex。例子用 HK property dataset(Datasetv2.csv,2020–2023 交易),抽 1000 rows:

data_path = "./Datasets/week_8/"
df_full = pd.read_csv(data_path + "Datasetv2.csv")
df_short = df_full.sample(1000, random_state=42)   # 固定 random_state,結果可重現
df_short['date'] = pd.to_datetime(df_short['date'], format='%d/%m/%Y', errors='coerce')
df_short['date'].max(), df_short['date'].min()     # 2023-03-09, 2020-03-11

address 例子:Grand Jete, Phase 1, Tower 2, 7/F, Flat J、Miami Mansion, 3/F, Flat 3、Tierra Verde, Phase 2, Block 10, Lower Floor, ...。

⭐ 考試重點:三個 regex 例子
# Task 1:抽 estate name(第一個逗號之前嘅部分)→ 用嚟同其他 dataset 合併計 per-estate trends
df['Estate'] = df['address'].str.extract(r'^(.*?)(?:,|$)')
#   Grand Jete, Phase 1, ...  → 'Grand Jete'
#   Miami Mansion, 3/F, ...   → 'Miami Mansion'

# Task 2:抽 Phase 編號
df['Phase'] = df['address'].str.extract(r'Phase\s+(\d+)')
#   'Phase 1' → '1';'Phase 4B' → '4';冇 Phase → NaN

# Task 3:數有幾多 rows 冇 floor pattern
floor_pattern = r"\b(?:Higher|Middle|Low|Lower)\s+Floor\b"
rows_without_floor_category = (
    ~df_short["address"].str.contains(floor_pattern, case=False, na=False)
).sum()
print(rows_without_floor_category)    # 771

逐個拆解:

  • ^(.*?)(?:,|$):^ 由開頭;( ) 係 capture group,str.extract() 回傳嘅就係呢部分;.*? 係 lazy(non-greedy):盡量 match 少啲字元;(?: ) 係 non-capturing group(只分組、唔抽出);,|$ 表示「遇到逗號或者去到字串尾」就停。所以抽到第一個逗號前嘅 estate name;冇逗號嘅地址就成個抽晒。
  • Phase\s+(\d+):字面 "Phase" + 一個或多個空白 + capture 一個或多個 digits。"4B" 只抽到 4,因為 \d 唔 match B。冇 match 嘅 row 回傳 NaN。
  • \b(?:Higher|Middle|Low|Lower)\s+Floor\b:\b 係 word boundary(防止 match 到 "Slower Floor" 呢類字中間);| 係 OR;case=False 唔分大細楷;na=False 將 missing 當 False;~ 反轉 Boolean;.sum() 數 True 嘅數目(True = 1)。
⚠️ 常見錯誤
  • Greedy vs lazy:如果寫 ^(.*)(?:,|$)(冇 ?),.* 會食到最後一個逗號,抽到 "Grand Jete, Phase 1, Tower 2, 7/F",唔係 estate name。
  • str.extract() 一定要有至少一個 capture group ( ),否則會出 error;(?: ) 唔計 capture group。
  • str.contains(pattern) default 會將 pattern 當 regex(regex=True),所以搵 "." 呢類特殊字元時要 escape 或者設 regex=False。

5. Scaling:點解要 scale?

  • 唔同 variables 通常有唔同 scales:例如一個 feature 係 0–10(產品價錢),另一個係 10,000–50,000(有幾多間店賣)。
  • Scaling:converting the scale of numeric data so that they're on a comparable scale。
  • 點解重要?例如 unsupervised learning 嘅 K-means clustering:clusters 係根據 inter-sample distances 搵出嚟,距離近嘅會被分入同一個 cluster。
⭐ 考試重點:K-means age / income 例子(slide p.12)
ageincome
John2531,000
Amy6030,000
Mike5528,000
d(J,A)=352+10002=1000.61,d(A,M)=52+20002=2000.01d(J, A) = \sqrt{35^2 + 1000^2} = 1000.61, \qquad d(A, M) = \sqrt{5^2 + 2000^2} = 2000.01

John 同 Amy 年齡相差 100%+,income 只差約 3%;但因為 income 嘅數值大好多,Euclidean distance 幾乎完全由 income 決定,結論變成「Amy 同 John 近過同 Mike」——age 完全冇影響力。Scaling 之後兩個 features 先至有可比較嘅影響力。

三種方法嘅共通目標:(或多或少)將 data 嘅 center 變 0、spread 變 1。

Demo data:9000 個 N(50,10)N(50, 10) 正常值 + 100 個 N(100,5)N(100, 5) 高端 outliers。

import numpy as np
X = pd.DataFrame({
    'value': np.concatenate([
        np.random.normal(50, 10, 9000),   # majority normal values
        np.random.normal(100, 5, 100),    # outliers on the high end
    ])
})
X.hist()   # 主峰喺 50 附近,100 附近有一小撮 outliers

6. Standard Scaling (StandardScaler)

  • 將 variables 轉成 standard normal variables(mean = 0, std = 1)。
  • 方法:減 mean,再除 standard deviation。
  • Mean 同 std 會被 outliers 拉動,但冇 min-max scaling 咁嚴重。
  • 唔會限制喺某個指定 range。
x′=x−meanstdx' = \frac{x - \text{mean}}{\text{std}}
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
X_ss = ss.fit_transform(X)
X_ss.mean()   # 4.06e-16 ≈ 0
X_ss.std()    # 1.0

Before / after histogram 嘅形狀完全一樣,只係 x-axis 由 20–120 變成大約 −3 至 6(outliers 喺 4 附近)。Scaling 係 linear transformation,唔會改變 distribution 形狀。

7. Min-max Scaling (MinMaxScaler)

  • 將 variables 轉成 (0, 1) interval 入面嘅連續值。
  • 將最小值 map 去 0、最大值 map 去 1。
  • Sensitive to outliers:想所有值喺 0 至 1 之間就好用,但可以被 outliers 嚴重影響。
x′=x−min⁡max⁡−min⁡x' = \frac{x - \min}{\max - \min}
from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler()
X_mm = mm.fit_transform(X)
X_mm.mean()   # 0.360
X_mm.std()    # 0.104   ← spread 好細

點解 std 只有 0.104?因為 max 係 outlier(約 120),正常值(30–70)全部被壓縮喺 0.2–0.5 呢個窄區間。Comparison plot 入面 MinMax 嘅 density curve 係一條好尖(peak ≈ 4)嘅窄峰。

8. Robust Scaling (RobustScaler)

  • 同 Min-Max 類似,但改為用 interquartile range。
  • 減 median,再按 quantile range scale(default 係 IQR = 25th 至 75th quantile 之間嘅距離)。
  • 將 IQR(Q3−Q1Q_3 - Q_1)map 成 1;避免 outliers 造成偏差。
  • Robust to outliers,但 唔保證 結果喺 0 至 1 之間。
x′=x−Q2Q3−Q1x' = \frac{x - Q_2}{Q_3 - Q_1}
from sklearn.preprocessing import RobustScaler
rs = RobustScaler()
X_rs = rs.fit_transform(X)
X_rs.mean()   # 0.025(median-centered,所以 mean 唔一定係 0)
X_rs.std()    # 0.831

Worked example(自己計,加深理解)

Data:x=[10,20,30,40,100]x = [10, 20, 30, 40, 100](100 係 outlier)。mean = 40,population std = 1000≈31.62\sqrt{1000} \approx 31.62,min = 10,max = 100,Q1=20Q_1 = 20,Q2=30Q_2 = 30,Q3=40Q_3 = 40,IQR = 20。

xStandard x−4031.62\frac{x-40}{31.62}Min-max x−1090\frac{x-10}{90}Robust x−3020\frac{x-30}{20}
10−0.9490−1.0
20−0.6320.111−0.5
30−0.3160.2220
4000.3330.5
1001.89713.5

觀察:Min-max 將 4 個正常值擠入 0–0.33;Robust 令正常值之間距離保持清楚(每 10 單位 = 0.5),outlier 就明顯咁「突出」喺 3.5,超出 [0, 1]。

9. Comparison of Scaling Methods

⭐ 考試重點:比較表
StandardScalerMinMaxScalerRobustScaler
公式x−meanstd\frac{x - \text{mean}}{\text{std}}x−min⁡max⁡−min⁡\frac{x - \min}{\max - \min}x−Q2Q3−Q1\frac{x - Q_2}{Q_3 - Q_1}
Effect on outliersModerately affected:mean、std 隨 outliers 移動Highly sensitive:outliers 將大部分 data 壓縮入細範圍Much less sensitive:median 同 IQR 減低極端值影響
Output range無固定 range;mean ≈ 0,unit variance固定,通常 [0, 1];保留 relative spacing無固定 range;保留 median-centered spread,對 long tails robust
When to preferAlgorithms assume zero-centered data:PCA、logistic regression、linear models、k-means需要 bounded range:neural networks with sigmoids、visualization、expect [0, 1] 嘅 algorithmsData 有 outliers,想減低影響但 唔 clip

Practical considerations

  • Exam Always fit scaler on training data only,再用已 fit 嘅 scaler transform validation / test data。
  • MinMaxScaler 喺新 data 超出 training 嘅 min/max 時會有問題(extrapolation:output 會 < 0 或 > 1)。
  • 有 outliers、而且要保留 non-outliers 之間嘅 relative order 時,RobustScaler 通常係 safe default。
  • StandardScaler 通常改善 gradient-based methods 嘅 convergence;MinMax 將 inputs bounded,可以加快 neural nets 訓練。
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X_train, X_test = train_test_split(X, test_size=0.2, random_state=42)
ss = StandardScaler()
X_train_s = ss.fit_transform(X_train)   # 只喺 train 計 mean / std
X_test_s  = ss.transform(X_test)        # test 用 train 嘅 mean / std,唔好再 fit!
⚠️ 常見錯誤:data leakage

如果喺成個 dataset(包括 test)先 fit scaler,test data 嘅資訊(佢嘅 mean、max 等)就「漏」咗入 training,test performance 會偏樂觀。對 test set 用 fit_transform 係錯,只可以 transform。

⭐ Quick rules of thumb
  • No strong outliers,algorithms assume normality 或者用 distances → StandardScaler。
  • Need fixed interval 或者 activation functions 嘅 inputs → MinMaxScaler。
  • Many outliers 或 heavy tails → RobustScaler。

10. Summary on Feature Transformation

  • Date and Time:用 .dt accessor。
  • Feature encoding:one-hot vs ordinal encoding 嘅 use cases。
  • Binning:cut() vs qcut() 嘅分別。
  • Cleaning texts:唔好忘記 string accessor .str;.str + string method 可以處理成個 column / df。
  • Feature scaling:唔同 scalers 嘅 use cases,幾時用邊個。

自我測驗 Self-test

Q1. nyc['PU_Address'].str.lower() 執行之後,nyc 入面嘅 column 變咗細楷未?

未。String methods 回傳新 Series,唔會 in-place 修改。要寫 nyc['PU_Address'] = nyc['PU_Address'].str.lower()。

Q2. 寫一行 code:數有幾多 rows 嘅 PU_Address(已 lower)含 "airport" 而且 Status 係 "Cancelled"。

nyc[nyc['PU_Address'].str.contains('airport') & (nyc['Status'] == 'Cancelled')].shape[0]。也可以用 (...).sum() 直接數 Boolean mask。注意 & 兩邊條件要加括號。

Q3. 以下邊個 strings 會被 ab+c match?"ac"、"abc"、"abbbc"。換成 ab*c 呢?

ab+c:abc、abbbc("ac" 唔得,因為 + 要至少一個 b)。ab*c:三個都 match(* 容許 0 個 b)。

Q4. re.findall(r'\d+', "Flat 12, 3/F, Block 7B") 回傳乜?

['12', '3', '7']。\d+ 抽每段連續 digits;"7B" 只抽到 7。

Q5. 點解抽 estate name 要用 ^(.*?)(?:,|$) 而唔係 ^(.*)(?:,|$)?(?:...) 有乜作用?

.*? 係 lazy,會喺第一個逗號停;.* 係 greedy,會食到最後一個逗號。(?:...) 係 non-capturing group:用嚟組合「逗號或字串尾」,但唔會被 str.extract() 抽出嚟,所以結果只有一個 column(estate name)。

Q6. Data = [2, 4, 6, 8, 50]。計 x = 8 嘅 min-max 同 robust scaled value(Q1=4Q_1 = 4,Q3=8Q_3 = 8)。

Min-max:8−250−2=648=0.125\frac{8 - 2}{50 - 2} = \frac{6}{48} = 0.125。Robust:median Q2=6Q_2 = 6,IQR = 8 − 4 = 4,8−64=0.5\frac{8 - 6}{4} = 0.5。Min-max 將 2–8 擠入 0–0.125,因為 outlier 50 決定咗 max。

Q7. Demo data 經 MinMaxScaler 之後 std 只有 0.104,經 RobustScaler 之後係 0.831。解釋點解。

MinMax 嘅分母係 max − min,被高端 outliers(約 100–120)撐大,正常值被壓縮喺細範圍,所以 spread 細。Robust 嘅分母係 IQR,只由中間 50% data 決定,唔受 outliers 影響,正常值保持原本嘅 spread(std 接近 1)。

Q8. 下面三個情況各揀邊個 scaler?(a) neural network 用 sigmoid activation;(b) income data 有好多極端富豪;(c) 冇明顯 outliers,做 PCA。

(a) MinMaxScaler(需要 bounded [0, 1] input);(b) RobustScaler(many outliers / heavy tail);(c) StandardScaler(PCA assume zero-centered data)。

Q9. 以下 code 有乜問題?
X_train_s = ss.fit_transform(X_train); X_test_s = ss.fit_transform(X_test)

Test set 唔應該再 fit。應該用 ss.transform(X_test),用 training data 嘅 mean / std。再 fit 會令 train 同 test 用唔同標準 scale,亦違反「fit on training data only」。

Q10. 喺 age/income 例子,點解 d(J, A) ≈ 1000.61 證明需要 scaling?

352+10002\sqrt{35^2 + 1000^2} 之中 352=122535^2 = 1225 相對 10002=1,000,0001000^2 = 1{,}000{,}000 可以忽略,distance 幾乎等於 income 差距。Age 差 35 年(100%+)完全冇影響 clustering,所以要 scale 到 comparable scale。

一頁總結 Cheat sheet

⭐ 考前速記
  • .str accessor:lower/upper(cases)、strip(頭尾空白、\n)、replace(abbreviations)、len(fixed-length 檢查)、contains(keyword filter)、startswith/endswith、.str[-3:] / .str[:-4](slicing)。
  • String methods 唔 in-place → 要 assign 返;contains case-sensitive(可設 case=False、na=False)。
  • 組合條件:df[(cond1) & (cond2)];反轉 ~;數目 .shape[0] 或 .sum()。
  • Regex:. 任意字元;\d digit;\w word char;\s whitespace;* 0+;+ 1+;? 0 或 1;^ 開頭;$ 結尾;\b word boundary;( ) capture;(?: ) non-capturing;| OR;.*? lazy。
  • re.findall(p, s) 回傳 list;re.sub(p, repl, s) 替換;s.str.extract(p) 抽 capture group(冇 match → NaN);s.str.contains(p) Boolean。
  • Scaling 原因:features scale 唔同 → distance-based algorithms(K-means)被大數值 feature 主導(352+10002=1000.61\sqrt{35^2 + 1000^2} = 1000.61)。
  • Standard:x−meanstd\frac{x - \text{mean}}{\text{std}},mean 0 std 1,無固定 range,outliers 中度影響。
  • Min-max:x−min⁡max⁡−min⁡\frac{x - \min}{\max - \min},[0, 1],對 outliers 最敏感,新 data 超出 min/max 有 extrapolation 問題。
  • Robust:x−Q2Q3−Q1\frac{x - Q_2}{Q_3 - Q_1},median-centered、IQR → 1,最 robust,但唔保證喺 [0, 1]。
  • Syntax:from sklearn.preprocessing import StandardScaler / MinMaxScaler / RobustScaler;X_s = scaler.fit_transform(X);輸出係 NumPy array。
  • Fit on training only → transform validation / test。
  • Rules:無 outliers / distances / normality → Standard;fixed interval / activation → MinMax;outliers / heavy tails → Robust。