返回文章列表

Python資料處理技術與程式碼解析

本文探討 Python 資料處理技巧,涵蓋常態分佈生成、資料標準化、CSV 與 JSON 格式轉換及資料整理。文章提供程式碼範例,解析 NumPy 和 Matplotlib 的應用,同時示範如何使用熱力圖和主成分分析 (PCA) 進行資料探索和降維,有效揭示資料內在結構和關聯性,並比較列表與生成器的速度差異。

資料科學 程式開發

資料處理是資料科學的根本,本篇文章將以 Python 為例,深入淺出地介紹資料處理的各種技巧。從常態分佈資料的生成與視覺化開始,我們會逐步探討如何利用 NumPy 和 Matplotlib 函式庫進行資料處理。接著,文章將示範資料標準化的流程與重要性,並以實際案例說明如何將 CSV 檔案轉換為 JSON 格式,同時進行資料的整理與重構。最後,我們將探討如何使用熱力圖和主成分分析 (PCA) 技術來進行資料探索和降維,以利於更深入地理解資料的內在結構和關聯性。同時,文章也包含了速度模擬的程式碼,比較了列表和生成器在處理大量資料時的效能差異,提供讀者在實務應用上的參考。

資料處理的實務應用與程式碼解析

在資料科學和資料分析的領域中,資料處理是一項至關重要的技能。本篇文章將透過五個程式碼範例,探討如何使用 Python 進行資料處理,包括常態分佈的生成、資料的標準化、CSV 檔案的讀取與 JSON 格式的轉換,以及資料的整理(Data Wrangling)。

常態分佈的生成與視覺化

首先,我們來看一個生成常態分佈資料並進行視覺化的例子。這個範例展示瞭如何使用 NumPy 和 Matplotlib 這兩個強大的 Python 函式庫來生成常態分佈的資料,並將其以直方圖和散點圖的形式呈現出來。

程式碼範例1:常態分佈的生成與視覺化

import numpy as np
import matplotlib.pyplot as plt

# 生成常態分佈資料
mu1, sigma1 = 10, 15
mu2, sigma2 = 5, 5
n = 1000
x1 = np.arange(n)
y1 = np.random.normal(mu1, sigma1, n)
x2 = np.arange(n)
y2 = np.random.normal(mu2, sigma2, n)

# 繪製直方圖
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.hist(y1, 30, color='r', alpha=0.7, label='Dataset 1')
plt.title('Dataset 1 (mu=10, sigma=15)')
plt.legend()

plt.subplot(2, 1, 2)
plt.hist(y2, 30, color='g', alpha=0.7, label='Dataset 2')
plt.title('Dataset 2 (mu=5, sigma=5)')
plt.legend()
plt.tight_layout()
plt.show()

內容解密:

  1. 資料生成:使用 np.random.normal 函式生成兩組常態分佈的資料,分別具有不同的平均值(mu)和標準差(sigma)。
  2. 視覺化:利用 Matplotlib 將生成的資料以直方圖的形式呈現,直觀地展示了兩組資料的分佈情況。
  3. plt.subplot:用於在同一個圖表視窗中建立多個子圖,便於比較不同資料集的分佈。

資料標準化

在比較不同資料集時,標準化是一個重要的步驟。下面的範例展示瞭如何將常態分佈的資料標準化,並比較標準化前後的差異。

程式碼範例2:資料標準化

# 資料標準化函式
def standardize(data, mu, sigma):
    return (data - mu) / sigma

# 對資料進行標準化
y1_std = standardize(y1, mu1, sigma1)
y2_std = standardize(y2, mu2, sigma2)

# 繪製標準化後的散點圖
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.scatter(x1, y1, color='r', alpha=0.5, label='Original Dataset 1')
plt.scatter(x2, y2, color='g', alpha=0.5, label='Original Dataset 2')
plt.title('Original Datasets')
plt.legend()

plt.subplot(2, 1, 2)
plt.scatter(x1, y1_std, color='r', alpha=0.5, label='Standardized Dataset 1')
plt.scatter(x2, y2_std, color='g', alpha=0.5, label='Standardized Dataset 2')
plt.title('Standardized Datasets')
plt.legend()
plt.tight_layout()
plt.show()

內容解密:

  1. 標準化函式:定義了一個簡單的函式來對資料進行標準化,公式為 (data - mu) / sigma,這使得資料具有零平均值和單位方差。
  2. 比較標準化前後的差異:透過散點圖展示了原始資料和標準化後的資料,可以觀察到標準化後的資料在尺度上具有可比性。

CSV 到 JSON 的轉換與資料整理

在實際工作中,經常需要處理不同格式的資料。下面的範例展示瞭如何將 CSV 檔案轉換為 JSON 格式,並進行資料整理。

程式碼範例3:CSV 到 JSON 的轉換

import csv
import json

# CSV 到 JSON 的轉換函式
def csv_to_json(csv_file, json_file):
    data = []
    with open(csv_file, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            data.append(row)
    with open(json_file, 'w') as f:
        json.dump(data, f)

# 資料整理函式
def wrangle_data(data):
    wrangled_data = []
    for i, row in enumerate(data):
        wrangled_row = {
            '_id': i,
            'customer': row['Customer Name'],
            'item': row['Sub-Category'],
            'sales': round(float(row['Sales']), 2),
            'quantity': row['Quantity'],
            'discount': row['Discount'],
            'profit': round(float(row['Profit']), 2),
            'segment': row['Segment']
        }
        wrangled_data.append(wrangled_row)
    return wrangled_data

# 主程式
csv_file = 'data/superstore.csv'
json_file = 'data/superstore.json'
csv_to_json(csv_file, json_file)
with open(json_file, 'r') as f:
    data = json.load(f)
wrangled_data = wrangle_data(data)
print(wrangled_data[:5])

內容解密:

  1. CSV 到 JSON 的轉換:使用 csvjson 模組實作了從 CSV 到 JSON 的轉換。
  2. 資料整理:定義了一個 wrangle_data 函式,對原始資料進行了重新整理和格式化,包括重新命名欄位和四捨五入數值。

資料探索的深度解析

在資料科學領域中,資料探索是一項至關重要的步驟。本章節將探討資料降維、速度模擬以及大型資料集的處理方法,並透過具體案例展示如何運用熱力圖和主成分分析(PCA)來揭露資料的內在結構。

熱力圖的應用

熱力圖是一種強大的視覺化工具,能夠直觀地呈現資料之間的相關性。在本案例中,我們將使用 wrangled.json 資料集來建立熱力圖,以展示銷售量、數量、折扣和利潤之間的關係。

程式碼實作

import json
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def read_json(f):
    with open(f) as f:
        return json.load(f)

def verify_keys(d, **kwargs):
    data = d[0].items()
    k1 = set([tup[0] for tup in data])
    s = kwargs.items()
    k2 = set([tup[1] for tup in s])
    return list(k1.intersection(k2))

def build_ls(k, d):
    return [{k: row[k] for k in (k)} for row in d]

def get_rows(d, n):
    [print(row) for i, row in enumerate(d) if i < n]

def conv_float(d):
    return [dict([k, float(v)] for k, v in row.items()) for row in d]

if __name__ == "__main__":
    f = 'data/wrangled.json'
    data = read_json(f)
    keys = verify_keys(data, c1='sale', c2='quan', c3='disc', c4='prof')
    heat = build_ls(keys, data)
    heat = conv_float(heat)
    df = pd.DataFrame(heat)
    plt.figure()
    sns.heatmap(df.corr(), annot=True, cmap='OrRd')
    plt.show()

內容解密:

  1. read_json 函式:讀取 JSON 檔案並傳回其內容。
  2. verify_keys 函式:驗證 JSON 資料中是否存在特定的鍵值,以確保資料的一致性。
  3. build_ls 函式:根據指定的鍵值建立一個字典列表,以便後續的資料處理。
  4. conv_float 函式:將字典中的值轉換為浮點數,確保資料的數值型別正確。
  5. sns.heatmap 函式:使用 Seaborn 函式庫建立熱力圖,展示資料之間的相關性。

主成分分析(PCA)

主成分分析是一種常用的資料降維技術,能夠找出資料中最主要的變異方向。在本案例中,我們將使用 PCA 對 wrangled.json 資料集進行分析,以揭露資料的內在結構。

程式碼實作

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import json
from sklearn.preprocessing import StandardScaler
from pandas.plotting import parallel_coordinates

# ...省略部分程式碼...

if __name__ == "__main__":
    f = 'data/wrangled.json'
    data = read_json(f)
    # ...省略部分程式碼...
    df = pd.DataFrame(numeric_data)
    X = df.ix[:].values
    X_std = StandardScaler().fit_transform(X)
    mean_vec = np.mean(X_std, axis=0)
    cov_mat = np.cov(X_std.T)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    # ...省略部分程式碼...
    var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)]
    cum_var_exp = np.cumsum(var_exp)
    fig, ax = plt.subplots()
    labels = ['PC1', 'PC2', 'PC3', 'PC4']
    width = 0.35
    index = np.arange(len(var_exp))
    ax.bar(index, var_exp, color=['fuchsia', 'lime', 'thistle', 'thistle'])
    # ...省略部分程式碼...
    plt.show()

內容解密:

  1. StandardScaler().fit_transform(X):對資料進行標準化處理,以確保資料的尺度一致。
  2. np.linalg.eig(cov_mat):計算共變異數矩陣的特徵值和特徵向量,以找出資料的主要變異方向。
  3. var_exp:計算每個主成分的解釋變異量,以評估其重要性。
  4. ax.bar(index, var_exp, ...):使用 Matplotlib 建立柱狀圖,展示每個主成分的解釋變異量。

主成分分析(PCA)與資料探索

主成分分析(PCA)是一種廣泛應用於資料降維和特徵提取的技術,能夠有效地簡化複雜的資料集並保留最重要的資訊。本篇文章將探討PCA的基本原理、應使用案例項以及如何透過程式碼實作PCA。

PCA的基本原理

PCA的核心思想是透過線性變換將原始資料投影到新的座標系中,使得資料在新的座標系中具有最大的變異數。具體步驟包括:

  1. 標準化資料:將原始資料標準化,以消除不同特徵之間的量綱差異。
  2. 計算協方差矩陣:計算標準化後的資料的協方差矩陣,以衡量不同特徵之間的相關性。
  3. 求解特徵值和特徵向量:對協方差矩陣進行特徵分解,得到特徵值和特徵向量。
  4. 選擇主成分:根據特徵值的大小選擇最重要的特徵向量作為主成分。

程式碼例項1:使用wrangled.json資料集進行PCA

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from pandas.plotting import parallel_coordinates

#### 內容解密:
- 匯入必要的函式庫包括matplotlibpandasnumpy和sklearn
- 使用`read_json()`函式讀取JSON檔案
- 使用`unique_features()`函式提取唯一的類別
- 使用`sire_features()`函式提取感興趣的特徵
- 使用`sire_numeric()`函式將數值字串轉換為浮點數

def read_json(f):
    with open(f) as f:
        return json.load(f)

def unique_features(feature, data):
    # 提取唯一的類別
    return np.unique([row[feature] for row in data])

def sire_features(data, features):
    # 提取感興趣的特徵
    return [{feature: row[feature] for feature in features} for row in data]

def sire_numeric(data):
    # 將數值字串轉換為浮點數
    return [{key: float(value) for key, value in row.items()} for row in data]

if __name__ == "__main__":
    data = read_json('wrangled.json')
    features = ['sale', 'quan', 'disc', 'prof']
    dataset_features = sire_features(data, features)
    dataset_numeric = sire_numeric(dataset_features)

    # 建立隨機樣本
    samples = []
    for category in unique_features('segm', data):
        sample = [row for row in data if row['segm'] == category]
        samples.append(random.sample(sample, 100))

    # 平行座標視覺化
    plt.figure()
    parallel_coordinates(pd.DataFrame(dataset_numeric), 'segm', color=['orange', 'lime', 'fuchsia'])
    plt.show()

    # PCA分析
    X_std = StandardScaler().fit_transform([list(row.values()) for row in dataset_numeric])
    cov_mat = np.cov(X_std.T)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    print('Eigenvectors:\n', eig_vecs)
    print('\nEigenvalues:\n', eig_vals)

    # 解釋變異數
    tot = sum(eig_vals)
    var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)]
    cum_var_exp = np.cumsum(var_exp)
    fig, ax = plt.subplots()
    labels = ['PC1', 'PC2', 'PC3', 'PC4']
    width = 0.35
    index = np.arange(len(var_exp))
    ax.bar(index, var_exp, color=['fuchsia', 'lime', 'thistle', 'thistle'])
    for i, v in enumerate(var_exp):
        v = round(v, 2)
        val = str(v) + '%'
        ax.text(i, v+0.5, val, ha='center', color='b', fontsize=9, fontweight='bold')
    plt.xticks(index, labels)
    plt.title('Variance Explained')
    plt.show()

內容解密:

  • 使用StandardScaler()對資料進行標準化。
  • 計算協方差矩陣並進行特徵分解。
  • 根據特徵值選擇主成分並進行視覺化。

程式碼例項2:使用iris資料集進行PCA

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from pandas.plotting import parallel_coordinates

def conv_float(d):
    return d.astype(float)

if __name__ == "__main__":
    df = pd.read_csv('data/iris.csv')
    X = df.iloc[:, 0:4].values
    y = df.iloc[:, 4].values
    X_std = StandardScaler().fit_transform(X)

    # PCA分析
    mean_vec = np.mean(X_std, axis=0)
    cov_mat = np.cov(X_std.T)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    print('Eigenvectors:\n', eig_vecs)
    print('\nEigenvalues:\n', eig_vals)

    # 平行座標視覺化
    plt.figure()
    parallel_coordinates(df, 'Name', color=['orange', 'lime', 'fuchsia'])
    plt.show()

    # 解釋變異數
    tot = sum(eig_vals)
    var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)]
    cum_var_exp = np.cumsum(var_exp)
    fig, ax = plt.subplots()
    labels = ['PC1', 'PC2', 'PC3', 'PC4']
    width = 0.35
    index = np.arange(len(var_exp))
    ax.bar(index, var_exp, color=['fuchsia', 'lime', 'thistle', 'thistle'])
    for i, v in enumerate(var_exp):
        v = round(v, 2)
        val = str(v) + '%'
        ax.text(i, v+0.5, val, ha='center', color='b', fontsize=9, fontweight='bold')
    plt.xticks(index, labels)
    plt.title('Variance Explained')
    plt.show()

內容解密:

  • 使用StandardScaler()對資料進行標準化。
  • 計算協方差矩陣並進行特徵分解。
  • 根據特徵值選擇主成分並進行視覺化。

速度模擬:列表與生成器的比較

import json
import humanfriendly as hf
from time import time

def read_json(f):
    with open(f) as f:
        return json.load(f)

def mk_gen(k, d):
    for row in d:
        dic = {}
        for key in k:
            dic[key] = float(row[key])
        yield dic

def conv_float(keys, d):
    return [dict([k, float(v)] for k, v in row.items() if k in keys) for row in d]

if __name__ == "__main__":
    f = 'data/wrangled.json'
    data = read_json(f)
    keys = ['sale', 'quan', 'disc', 'prof']

    start = time()
    data_list = conv_float(keys, data)
    for i, row in enumerate(data_list):
        if i < 5:
            print(row)
    end = time()
    elapsed_ls = end - start
    print(hf.format_timespan(elapsed_ls, detailed=True))

    start = time()
    generator = mk_gen(keys, data)
    for i, row in enumerate(generator):
        if i < 5:
            print(row)
    end = time()
    elapsed_gen = end - start
    print(hf.format_timespan(elapsed_gen, detailed=True))

    speed = round(elapsed_ls / elapsed_gen, 2)
    print('Generator is', speed, 'times faster')

內容解密:

  • 使用mk_gen()函式建立生成器。
  • 使用conv_float()函式將列表中的數值字串轉換為浮點數。
  • 比較列表和生成器的執行速度。