資料處理是資料科學的根本,本篇文章將以 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()
內容解密:
- 資料生成:使用
np.random.normal函式生成兩組常態分佈的資料,分別具有不同的平均值(mu)和標準差(sigma)。 - 視覺化:利用 Matplotlib 將生成的資料以直方圖的形式呈現,直觀地展示了兩組資料的分佈情況。
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()
內容解密:
- 標準化函式:定義了一個簡單的函式來對資料進行標準化,公式為
(data - mu) / sigma,這使得資料具有零平均值和單位方差。 - 比較標準化前後的差異:透過散點圖展示了原始資料和標準化後的資料,可以觀察到標準化後的資料在尺度上具有可比性。
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])
內容解密:
- CSV 到 JSON 的轉換:使用
csv和json模組實作了從 CSV 到 JSON 的轉換。 - 資料整理:定義了一個
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()
內容解密:
read_json函式:讀取 JSON 檔案並傳回其內容。verify_keys函式:驗證 JSON 資料中是否存在特定的鍵值,以確保資料的一致性。build_ls函式:根據指定的鍵值建立一個字典列表,以便後續的資料處理。conv_float函式:將字典中的值轉換為浮點數,確保資料的數值型別正確。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()
內容解密:
StandardScaler().fit_transform(X):對資料進行標準化處理,以確保資料的尺度一致。np.linalg.eig(cov_mat):計算共變異數矩陣的特徵值和特徵向量,以找出資料的主要變異方向。var_exp:計算每個主成分的解釋變異量,以評估其重要性。ax.bar(index, var_exp, ...):使用 Matplotlib 建立柱狀圖,展示每個主成分的解釋變異量。
主成分分析(PCA)與資料探索
主成分分析(PCA)是一種廣泛應用於資料降維和特徵提取的技術,能夠有效地簡化複雜的資料集並保留最重要的資訊。本篇文章將探討PCA的基本原理、應使用案例項以及如何透過程式碼實作PCA。
PCA的基本原理
PCA的核心思想是透過線性變換將原始資料投影到新的座標系中,使得資料在新的座標系中具有最大的變異數。具體步驟包括:
- 標準化資料:將原始資料標準化,以消除不同特徵之間的量綱差異。
- 計算協方差矩陣:計算標準化後的資料的協方差矩陣,以衡量不同特徵之間的相關性。
- 求解特徵值和特徵向量:對協方差矩陣進行特徵分解,得到特徵值和特徵向量。
- 選擇主成分:根據特徵值的大小選擇最重要的特徵向量作為主成分。
程式碼例項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
#### 內容解密:
- 匯入必要的函式庫,包括matplotlib、pandas、numpy和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()函式將列表中的數值字串轉換為浮點數。 - 比較列表和生成器的執行速度。