一、今天的學習目標
今天主要會練習以下幾個功能:
使用 Pandas 新增資料欄位。
使用 apply() 和條件判斷分類資料。
使用 value_counts() 統計不同類別的數量。
使用 groupby() 分析各類別的平均價格。
將分析結果輸出成 CSV,方便後續使用。
二、建立書籍資料
實際進行資料分析時,我們通常會先把資料整理成 DataFrame。為了讓程式可以直接在 Google Colab 執行,今天先建立一組模擬書籍資料。
這些資料包含書名、價格和評分,之後也可以替換成前幾天從 Books to Scrape 爬取的資料。
import pandas as pd
data = {
"title": [
"Book A",
"Book B",
"Book C",
"Book D",
"Book E",
"Book F",
"Book G",
"Book H"
],
"price": [
15.99,
25.50,
8.99,
45.00,
32.99,
12.50,
55.00,
19.99
],
"rating": [
5, 4, 3, 5, 2, 4, 5, 3
]
}
df = pd.DataFrame(data)
print(df)
執行後會得到一張書籍資料表,每一列代表一本書,而每個欄位則代表書籍的一項資訊。
目前我們只有原始價格和評分。如果想知道哪些書比較便宜、哪些書屬於高價位,就需要進一步處理資料。
三、新增欄位:將價格轉換成分類
假設我們想將書籍分成三種價格區間:
價格低於 20:便宜
價格介於 20 到 40:中價位
價格高於 40:高價位
這時可以新增一個 price_category 欄位,讓每本書都擁有自己的價格分類。
def classify_price(price):
if price < 20:
return "便宜"
elif price <= 40:
return "中價位"
else:
return "高價位"
df["price_category"] = df["price"].apply(classify_price)
print(df)
這裡有兩個需要理解的地方。
第一個是 classify_price()。它接收一個價格,透過 if、elif 和 else 判斷價格屬於哪個區間,最後回傳分類結果。
第二個是:
df["price"].apply(classify_price)
apply() 會將函式套用到 price 欄位的每一筆資料,再把結果放進新的 price_category 欄位。
例如,價格是 15.99 的書會被分類成「便宜」,價格是 45.00 的書則會被分類成「高價位」。
這樣一來,我們就不只是保存原始數字,也能從資料中建立更有意義的資訊。
四、統計每種價格區間有幾本書
完成分類後,接下來可以使用 value_counts() 統計每個類別出現的次數。
category_count = df["price_category"].value_counts()
print(category_count)
這個方法會計算每個價格分類出現了幾次,並預設按照數量由多到少排列。
如果想將結果整理成適合輸出的 DataFrame,可以再加上 reset_index():
category_summary = (
df["price_category"]
.value_counts()
.reset_index()
)
category_summary.columns = ["price_category", "book_count"]
print(category_summary)
整理之後,結果會包含兩個欄位:
price_category:價格分類。
book_count:該分類的書籍數量。
這種統計方式很常用。例如,分析商品資料時,可以統計不同價格帶的商品數量;分析問卷時,也可以統計不同選項被選擇的次數。
五、使用 groupby 分析不同價格區間
知道各類別有幾本書之後,我還想知道不同價格區間的平均價格是多少。
這時就可以結合昨天學過的 groupby() 和 agg()。
price_summary = (
df.groupby("price_category")["price"]
.agg(["count", "mean", "min", "max"])
.reset_index()
)
price_summary.columns = [
"price_category",
"book_count",
"average_price",
"minimum_price",
"maximum_price"
]
print(price_summary.round(2))
這段程式會按照 price_category 分組,再針對每一組的價格計算:
count:書籍數量。
mean:平均價格。
min:最低價格。
max:最高價格。
round(2) 則是將數字四捨五入到小數點後兩位,讓價格資料更容易閱讀。
透過這個結果,我們可以比較不同價格區間的資料,也能檢查分類是否符合原本的預期。
要注意的是,這裡的價格區間是我們自行設定的分析規則,不代表實際市場一定會使用相同的分類方式。
六、找出每個價格區間最貴的書
接下來,我想進一步找出每個價格區間中價格最高的書籍。
我們可以使用 groupby() 分組,再搭配 idxmax() 找出每組價格最大值所在的索引。
max_price_index = (
df.groupby("price_category")["price"]
.idxmax()
)
most_expensive_books = df.loc[max_price_index]
print(
most_expensive_books[
["title", "price", "price_category"]
]
)
這裡的 idxmax() 回傳的是每個分類中,價格最高那筆資料的索引位置,而不是直接回傳價格。
接著使用 df.loc[],就能根據索引找回完整的書籍資料。
這個方法不只可以找出最貴的書,也能用來找出每個商品類別中評價最高的商品,或是每個部門中業績最高的紀錄。
七、將分析結果輸出成 CSV
分析完成後,我們可以將結果儲存起來,方便後續整理報告,或是在下一階段匯入資料庫。
df.to_csv(
"books_with_categories.csv",
index=False,
encoding="utf-8-sig"
)
price_summary.to_csv(
"price_summary.csv",
index=False,
encoding="utf-8-sig"
)
print("資料已成功輸出!")
這裡會產生兩份 CSV:
books_with_categories.csv:包含原始書籍資料與新增的價格分類。
price_summary.csv:包含各價格區間的統計結果。
index=False 可以避免把 Pandas 的索引另外輸出成一個欄位;utf-8-sig 則有助於讓包含中文的 CSV 在部分 Windows 版 Excel 中正常顯示。
如果要從 Google Colab 下載檔案,可以執行:
from google.colab import files
files.download("books_with_categories.csv")
files.download("price_summary.csv")
八、套用到前幾天爬取的書籍資料
前面使用的是模擬資料。如果之前的爬蟲程式已經將書籍資料整理成 all_books,也可以直接轉成 DataFrame。
不過,要先確認價格和評分都是數字,而不是像 "£51.77" 或 "Three" 這樣的文字。
如果資料中的價格已經是數字、評分也已經轉換成 1 到 5,可以這樣處理:
df = pd.DataFrame(all_books)
df["price"] = pd.to_numeric(
df["price"],
errors="coerce"
)
df["rating"] = pd.to_numeric(
df["rating"],
errors="coerce"
)
df = df.dropna(subset=["price", "rating"])
df["price_category"] = df["price"].apply(
classify_price
)
print(df.head())
pd.to_numeric() 會嘗試把欄位轉成數字;遇到無法轉換的內容時,errors="coerce" 會將它轉成缺失值,再透過 dropna() 排除價格或評分無效的資料。
如果你的 all_books 裡面存的價格仍是英鎊文字,或評分仍是 "One"、"Two" 等英文,必須先做對應的清理與轉換,才能正確分析。這也呼應了前幾天學過的資料清理概念。
九、今天的學習心得
今天練習了如何使用 Pandas 新增欄位,並把原始的價格資料轉換成不同分類。接著透過 value_counts()、groupby() 和 idxmax(),統計各類別的數量、價格分布,以及每個分類中最貴的書籍。
我發現資料分析不只是把數字算出來,更重要的是先思考自己想回答什麼問題,再決定要怎麼整理資料。例如,原本只有價格的資料,經過分類之後,就可以更直觀地比較不同價格區間的書籍。
接下來,我會繼續把前面學過的爬蟲、資料清理和 Pandas 分析串起來,讓資料從取得、整理到分析的流程更加完整,也為後續的 SQLite 資料庫應用做準備。