iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
自我挑戰組

Python × 政府開放資料:30天數據探索與圖表呈現系列 第 9

Day 9 讀取資料&資料清理(處理0值)

  • 分享至 

  • xImage
  •  

今天開始進行實作:先讀取資料並檢查品質。使用pandas載入CSV後,我們先用df.info()、df.head()確認欄位,再用df.describe()查看數據分布。和一般資料集不同,這份臺北市觀光遊憩統計的缺漏值並沒有以NaN表示,而是直接補上了0。

這樣的處理方式雖然讓我們少了「缺值」的麻煩,但同時帶來一個挑戰 - 0的意義不一定相同。有0代表真的沒有遊客(例如臨時封閉或淡季),但有些可能是因為該年份沒有統計資料,被直接填0。這會影響我們的趨勢判斷。

舉例來說,若我們繪製折線圖,遇到0就會出現「斷崖式下降」,可能看起來像是人潮驟減,但實際上可能只是該年沒有營運。

這時候,我們有兩種策略:

  • 保留0:代表當月確實沒有營運或遊客,保持數據原貌。
  • 將0視為缺值:轉換成NaN,再用interpolate()插值平滑補齊,避免趨勢斷裂。
    實作上,如果要把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()

https://ithelp.ithome.com.tw/upload/images/20250907/20178624Rs4wDfbLBK.pnghttps://ithelp.ithome.com.tw/upload/images/20250907/20178624vMgEmxhO4f.pnghttps://ithelp.ithome.com.tw/upload/images/20250907/20178624nxWSIazCiT.pnghttps://ithelp.ithome.com.tw/upload/images/20250907/20178624Sr4dVSvntf.png


上一篇
Day 8 資料集介紹 – 臺北市主要觀光遊憩區遊客人次
系列文
Python × 政府開放資料:30天數據探索與圖表呈現9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言