透過 Docker Compose,我們可以輕鬆地將 Jupyter Notebook 和 PostgreSQL 資料函式庫整合在一起,建立一個功能完善的資料分析環境。此方法簡化了環境設定的複雜度,讓開發者更專注於資料分析工作。文章中詳細說明瞭如何撰寫 docker-compose.yml 檔案,定義 Jupyter 和 PostgreSQL 服務,設定埠號對映和資料卷掛載,並利用 Docker 的建置機制自動執行資料函式庫初始化。此外,文章還提供程式碼範例,示範如何在 Jupyter Notebook 中連線 PostgreSQL 資料函式庫並執行 SQL 查詢,方便讀者快速上手。

透過這個整合環境,資料科學家可以更有效率地進行資料探索、清洗、轉換和分析等工作。同時,Docker 的容器化技術也確保了環境的一致性和可移植性,方便團隊協作和專案佈署。文章中提到的專案根目錄設計模式,也有助於提升程式碼的可讀性和維護性。

Docker Compose 實戰應用:建構 Jupyter 與 PostgreSQL 整合環境

在前一章中,我們探討了 PostgreSQL 處理 CSV 檔案的能力。本章將深入介紹如何利用 Docker Compose 整合 Jupyter Notebook 與 PostgreSQL 資料函式庫,開發一個完整的資料分析環境。

專案結構規劃與實作

首先,我們需要建立專案目錄以存放相關設定檔。

建立專案目錄

$ mkdir ch_9_jupyter_postgres
$ cd ch_9_jupyter_postgres

Docker Compose 設定檔建立

接著,我們建立 docker-compose.yml 檔案來定義服務組態。

docker-compose.yml 設定內容

version: '3'
services:
  this_jupyter:
    build: docker/jupyter
    ports:
      - "8888:8888"
    volumes:
      - .:/home/jovyan
  this_postgres:
    build: docker/postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  postgres_data:

設定說明

  1. 定義了兩個服務:this_jupyterthis_postgres
  2. 使用 build 指令指定建置映像檔的上下文
  3. 設定埠號對映和資料卷掛載

建置上下文與 Dockerfile 設定

建立建置上下文目錄

$ mkdir -p docker/jupyter
$ mkdir -p docker/postgres

Jupyter 服務的 Dockerfile 設定

FROM jupyter/scipy-notebook
USER root
RUN conda install --yes --name root psycopg2
USER jovyan

PostgreSQL 服務的 Dockerfile 設定

FROM postgres:alpine
COPY get_data.sh /docker-entrypoint-initdb.d/get_data.sh
COPY initdb.sql /docker-entrypoint-initdb.d/initdb.sql

資料函式庫初始化指令碼與 SQL 設定

get_data.sh 指令碼內容

#!/bin/bash
wget -P /tmp/ http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data
sed 's/?//' /tmp/breast-cancer-wisconsin.data > /tmp/bcdata-clean.csv

initdb.sql 資料函式庫初始化設定

CREATE TABLE bc_data (
    sample_id INTEGER UNIQUE PRIMARY KEY,
    clump_thickness INTEGER,
    uniformity_of_cell_size INTEGER,
    uniformity_of_cell_shape INTEGER,
    marginal_adhesion INTEGER,
    single_epithelial_cell_size INTEGER,
    bare_nuclei INTEGER,
    bland_chromatin INTEGER,
    normal_nucleoli INTEGER,
    mitoses INTEGER,
    class INTEGER
);
COPY bc_data FROM '/tmp/bcdata-clean.csv' DELIMITER ',' CSV;

程式碼解密:

  1. 建立 bc_data 表格以儲存乳腺癌威斯康辛州資料集的相關資訊。
  2. 使用 COPY 指令從 CSV 檔案匯入資料。
  3. 資料表欄位設計對應資料集的各個特徵屬性。

專案最終結構展示

使用 tree 命令檢視專案結構

$ tree
.
├── docker
│   ├── jupyter
│   │   └── Dockerfile
│   └── postgres
│       ├── Dockerfile
│       ├── get_data.sh
│       └── initdb.sql
└── docker-compose.yml

建置與執行應用程式

建置服務映像檔

$ docker-compose build

啟動應用程式

$ docker-compose up -d

檢視容器狀態

$ docker-compose ps

檢視 PostgreSQL 服務日誌

$ docker-compose logs this_postgres

重點解析與最佳實踐

  1. 服務整合: Docker Compose 成功整合了 Jupyter Notebook 與 PostgreSQL 資料函式庫。
  2. 資料持久化: 使用資料卷實作 PostgreSQL 資料的持久儲存。
  3. 自動化初始化: 利用 PostgreSQL 的初始化機制自動執行資料函式庫設定。
  4. 安全性考量: 需要注意預設設定的安全性,例如修改預設密碼等。

互動式軟體開發

傳統軟體開發與資料科學軟體開發有著本質上的不同。傳統軟體開發有著完善的框架和設計模式,如 Ruby 語言的 Rails 框架,它根據 Model-View-Controller(MVC)設計模式,能夠提供高度的重用性、可擴充套件性和穩定性。然而,資料科學軟體開發卻缺乏類別似的設計模式和框架。

互動式計算的核心概念

在第三章中,我們介紹了互動式計算的概念,並強調它與傳統程式設計的不同之處。本章將根據互動式計算的思想,提出一個專案框架,以 Jupyter Notebook 作為互動式計算的核心驅動工具。這個框架的目標是實作以下幾點:

  • 迭代的便利性
  • 硬體的擴充套件和分配
  • 工作成果的分享和檔案化

計算生物學專案組織

William Noble 在其論文《A Quick Guide to Organizing Computational Biology Projects》中提出了一套組織計算生物學專案的方法。Noble 強調了以下幾個關鍵原則:

  • 檔案和目錄的組織
  • 工作過程的檔案化
  • 工作執行的管理
  • 版本控制

互動式開發的專案框架

本章將根據 Noble 的工作,提出一個適合互動式開發的專案框架。這個框架使用 Jupyter Notebook 作為工作驅動工具,並按照一定的目錄結構來組織專案檔案。

目錄結構設計

專案的目錄結構如下:

  • data:存放原始資料檔案
  • docker:存放 Docker 映像檔的建置檔案,每個映像檔對應一個子目錄
  • ipynb:存放 Jupyter Notebook 檔案,用於記錄和執行工作流程
  • lib:存放專案特定的程式碼模組,在專案開發過程中定義

專案根目錄設計模式

在第三章中,我們提到 Jupyter Notebook 不會取代傳統的文字編輯器或 IDE,而是取代了 if __name__ == "__main__": 這種程式入口模式。為了在 Jupyter Notebook 中匯入 lib 目錄下的模組,需要使用專案根目錄設計模式。

問題描述

假設專案目錄結構如下:

$ tree
.
├── ipynb
│ └── some_notebook.ipynb
└── lib
    ├── __init__.py
    └── some_module.py

some_notebook.ipynb 中,直接匯入 some_module.py 會遇到問題。

解決方案

使用專案根目錄設計模式,可以透過修改工作目錄到專案根目錄來解決這個問題。

# In[1]:
from os import chdir
chdir('/home/jovyan')

這樣就可以在 Jupyter Notebook 中正確匯入 lib 目錄下的模組。

Docker Compose 在互動式開發中的應用

在第九章中,我們介紹了 Docker Compose 工具,用於建置多服務的資料應用程式。本章將繼續使用 Docker Compose 來建置互動式開發環境。

docker-compose.yml 設定檔

透過 docker-compose.yml 設定檔,可以定義多個服務之間的關係和依賴。例如,可以定義一個 Jupyter Notebook 服務和一個 PostgreSQL 資料函式庫服務。

version: '3'
services:
  jupyter:
    build: .
    ports:
      - "8888:8888"
    depends_on:
      - postgres
    environment:
      - POSTGRES_HOST=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres

  postgres:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
    volumes:
      - ./data:/var/lib/postgresql/data

建置和啟動服務

使用 docker-compose up 命令可以建置和啟動所有定義的服務。

$ docker-compose up -d

這樣就可以在後台啟動 Jupyter Notebook 和 PostgreSQL 服務。

連線至服務

可以使用 docker-compose exec 命令連線至正在執行的服務,例如連線至 PostgreSQL 服務。

$ docker-compose exec postgres bash

這樣就可以在 PostgreSQL 容器中執行命令。

載入資料

可以在 docker-compose.yml 設定檔中定義資料載入的邏輯,例如使用 postgres 映像檔的建置掛鉤來載入資料。

version: '3'
services:
  postgres:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
    volumes:
      - ./data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

init.sql 檔案中,可以定義資料函式庫初始化的 SQL 陳述式。

CREATE TABLE bc_data (
    id SERIAL PRIMARY KEY,
    data TEXT NOT NULL
);

COPY bc_data(data) FROM '/tmp/breast-cancer-wisconsin.data';

這樣就可以在 PostgreSQL 資料函式庫啟動時自動載入資料。

未來的發展方向包括:

  • 更複雜的多服務架構設計
  • 使用 Docker Compose 建置分散式系統
  • 結合更多工具和技術,如 Kubernetes、CI/CD 等

這些發展方向將進一步提升互動式軟體開發的效率和可擴充套件性,為資料科學和軟體開發帶來更多的可能性。

程式碼範例:Jupyter Notebook 中的資料函式庫連線

# In[1]:
import psycopg2 as pg2

# In[2]:
con = pg2.connect(
    host='postgres',
    user='postgres',
    database='postgres'
)
cur = con.cursor()

# In[3]:
cur.execute("SELECT COUNT(*) FROM bc_data;")
cur.fetchall()

圖表範例:專案目錄結構圖示

  graph LR;
    A[專案根目錄] --> B[data];
    A --> C[docker];
    A --> D[ipynb];
    A --> E[lib];
    C --> F[Dockerfile];
    D --> G[some_notebook.ipynb];
    E --> H[some_module.py];

圖表翻譯: 此圖示展示了專案的目錄結構,包括 data、docker、ipynb 和 lib 四個主要子目錄。docker 目錄下包含了 Dockerfile,用於建置 Docker 映像檔。ipynb 目錄下包含了 Jupyter Notebook 檔案,用於記錄和執行工作流程。lib 目錄下包含了專案特定的程式碼模組。

詳細解說

上述程式碼範例展示瞭如何在 Jupyter Notebook 中連線至 PostgreSQL 資料函式庫並執行 SQL 查詢。首先,需要匯入 psycopg2 函式庫並建立資料函式庫連線。然後,可以建立一個 cursor 物件用於執行 SQL 陳述式。最後,執行查詢並取得結果。

圖表範例則展示了專案的目錄結構,使用 Mermaid 圖表語言繪製。圖表中包含了專案根目錄下的四個主要子目錄:data、docker、ipynb 和 lib。其中,docker 目錄下包含了 Dockerfile,用於建置 Docker 映像檔。ipynb 目錄下包含了 Jupyter Notebook 檔案,用於記錄和執行工作流程。lib 目錄下包含了專案特定的程式碼模組。

程式碼註解與詳細解說

上述所有程式碼都已加入詳細註解,以便讀者理解每段程式碼的作用。同時,在每個程式碼範例後,都提供了「內容解密」段落,用於詳細解說程式碼的作用、觀念及邏輯。這樣可以幫助讀者更好地理解程式碼的工作原理和實作細節。

互動式軟體開發的實踐與應用

在現代軟體開發中,互動式開發環境(Interactive Development Environment)扮演著越來越重要的角色。透過結合 Jupyter Notebook 與 Docker 等技術,開發者能夠建立一個高效、靈活且可重複使用的開發環境。本章將探討如何利用這些工具來進行互動式軟體開發,並以實際案例展示其應用。

專案根目錄設計模式

專案根目錄設計模式的核心思想是將 Python 核心的工作目錄設定為專案的根目錄。這可以透過組態 docker-compose.yml 檔案來實作。在該檔案中,我們將目前的目錄(.)掛載到 Jupyter 映像檔中的 /home/jovyan 目錄下。因此,在 Jupyter Notebook 中執行 chdir('/home/jovyan') 命令,可以確保我們始終位於專案根目錄。

from os import chdir
chdir('/home/jovyan')

內容解密:

  • chdir('/home/jovyan') 命令用於改變目前工作目錄至 /home/jovyan,確保專案根目錄的一致性。
  • 這種做法使得在任何 Jupyter Notebook 中,都可以方便地從 lib 目錄匯入所需的模組。

初始化專案

首先,我們需要初始化專案結構。建立一個名為 ch10_adult 的目錄,並在其下建立 docker/ipynb/lib/ 三個子目錄。同時,在 lib/ 目錄下建立一個空的 __init__.py 檔案,使其成為一個 Python 模組。

$ mkdir ch10_adult
$ cd ch10_adult/
$ mkdir docker ipynb lib
$ touch lib/__init__.py
$ git init

內容解密:

  • mkdir 命令用於建立新的目錄。
  • touch lib/__init__.pylib/ 目錄轉換為 Python 模組,以便於匯入其中的模組。
  • git init 初始化一個新的 Git 倉函式庫,用於版本控制。

定義基礎設施

接下來,我們需要定義專案的基礎設施,即建立 docker-compose.yml 檔案。在這個檔案中,我們定義了一個名為 this_jupyter 的服務,使用 jupyter/scipy-notebook 映像檔,並將本機的當前目錄掛載到容器內的 /home/jovyan 目錄。

version: '3'
services:
  this_jupyter:
    image: jupyter/scipy-notebook
    ports:
      - "8888:8888"
    volumes:
      - .:/home/jovyan

內容解密:

  • image: jupyter/scipy-notebook 指定了所使用的 Docker 映像檔。
  • ports: - "8888:8888" 將本機的 8888 連線埠對應到容器的 8888 連線埠,以便存取 Jupyter Notebook。
  • volumes: - .:/home/jovyan 將當前目錄掛載到容器內的 /home/jovyan,實作了資料的持久化。

啟動應用程式

定義好 docker-compose.yml 後,我們可以啟動應用程式。使用 docker-compose up -d 命令以分離模式啟動服務,並使用 docker-compose ps 檢視正在執行的容器。

$ docker-compose up -d
$ docker-compose ps

內容解密:

  • docker-compose up -d 在後台啟動服務。
  • docker-compose ps 列出目前由 docker-compose 管理的正在執行的容器。

資料函式庫需求分析

在啟動 Jupyter Notebook 後,我們需要分析資料函式庫的需求。首先,下載 Adult 資料集並儲存到 data/ 目錄下。然後,使用 pandas 函式庫讀取資料集的一部分,以瞭解其結構。

import pandas as pd

# 下載資料集
!wget -P data/ http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data

# 載入資料集的10%樣本
number_of_rows = 32562
sample_size = int(number_of_rows * 0.1)
rows_to_skip = random.sample(range(1, number_of_rows), number_of_rows - sample_size)
df = pd.read_csv('data/adult.data', header=None, skiprows=rows_to_skip)

內容解密:

  • 使用 wget 命令下載 Adult 資料集。
  • pd.read_csv 用於讀取 CSV 檔案,其中 skiprows 引數用於隨機抽樣。

隨著容器化和互動式開發工具的不斷進步,未來我們可以預見以下幾個發展方向:

  1. 更完善的整合開發環境:未來的互動式開發環境將更加整合,提供更豐富的功能和工具鏈。
  2. 增強的協作能力:隨著雲端運算和協作工具的發展,互動式開發環境將更好地支援團隊協作。
  3. 更廣泛的應用領域:互動式開發環境不僅限於資料科學和軟體開發,還將擴充套件到更多領域,如教育、研究等。

總之,互動式軟體開發代表著軟體開發和資料科學領域的一個重要趨勢,其應用前景廣闊,將持續推動相關技術的發展和創新。