今天開始進行實作:先讀取資料並檢查品質。使用pandas載入CSV後,我們先用df.info()、df.head()確認欄位,再用df.describe()查看數據分布。和一般資料集不同,這份臺北市觀光遊憩統計的缺漏值並沒有以NaN表示,而是直接補上了0。
這樣的處理方式雖然讓我們少了「缺值」的麻煩,但同時帶來一個挑戰 - 0的意義不一定相同。有0代表真的沒有遊客(例如臨時封閉或淡季),但有些可能是因為該年份沒有統計資料,被直接填0。這會影響我們的趨勢判斷。
舉例來說,若我們繪製折線圖,遇到0就會出現「斷崖式下降」,可能看起來像是人潮驟減,但實際上可能只是該年沒有營運。
這時候,我們有兩種策略:
import numpy as np
df.replace(0, np.nan, inplace=True)
df.interpolate(inplace=True)
這樣的處理讓時間序列更連續,對於長期趨勢觀察更合理。當然,究竟要保留還是補齊,要依分析目標來決定。整理好後,我們還要把「統計期」轉成datetime並設為索引,才能方便後續的時間序列分析。
這份程式碼執行後會產生三張圖:
原始資料(保留0)
插值補齊後
對照圖(保留0 vs補缺值)
這樣讀者可以清楚看到0是否補值對時間序列趨勢的影響。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 設定中文字型
plt.rcParams["font.family"] = "Heiti TC"
plt.rcParams["axes.unicode_minus"] = False
# 讀取資料
df = pd.read_csv("IT_Taipei_tourism/IT_Taipei_tourism.csv")
# 基本檢查
print(df.info())
print(df.head())
print(df.describe())
# 民國年轉西元年(只有年份 → 自動補1月)
def roc_to_ad(date_str):
if pd.isna(date_str):
return None
year = int(str(date_str).replace("年", "").strip()) + 1911
return year
# 套用轉換
df["統計期"] = df["統計期"].apply(roc_to_ad)
df["統計期"] = pd.to_datetime(df["統計期"], format="%Y", errors="coerce")
print(df.head())
# ---------------------------
# 方法一:保留 0(原始資料)
# ---------------------------
plt.figure(figsize=(12, 6))
plt.plot(df.index, df["國立臺灣科學教育館遊客人次"], label="保留 0")
plt.title("國立臺灣科學教育館遊客人次(保留 0)")
plt.xlabel("年份")
plt.ylabel("參觀人次")
plt.legend()
plt.show()
# ---------------------------
# 方法二:將 0 視為缺值並插值補齊
# ---------------------------
df_interpolated = df.copy()
df_interpolated.replace(0, np.nan, inplace=True)
df_interpolated.interpolate(inplace=True)
plt.figure(figsize=(12, 6))
plt.plot(
df_interpolated.index,
df_interpolated["國立臺灣科學教育館遊客人次"],
label="補缺值後",
)
plt.title("國立臺灣科學教育館遊客人次(插值處理)")
plt.xlabel("年份")
plt.ylabel("參觀人次")
plt.legend()
plt.show()
# ---------------------------
# 對照圖(保留 0 vs 補缺值)
# ---------------------------
plt.figure(figsize=(12, 6))
plt.plot(df.index, df["國立臺灣科學教育館遊客人次"], label="保留 0", alpha=0.7)
plt.plot(
df_interpolated.index,
df_interpolated["國立臺灣科學教育館遊客人次"],
label="補缺值後",
alpha=0.7,
)
plt.title("動物園參觀人次(保留 0 vs 補缺值)")
plt.xlabel("年份")
plt.ylabel("參觀人次")
plt.legend()
plt.show()