Python 的集合(set)提供高效的成員測試和去重複功能,搭配 defaultdict 和 Counter 更能簡化資料處理流程。生成器運算式能精簡程式碼,提升資料提取效率。理解這些工具的特性,能有效處理貨幣資料、統計字詞頻率、分析文字資料等常見任務。善用集合運算元,能快速進行聯集、交集、差集等操作,提升程式碼簡潔度。這些技巧對於提升 Python 資料處理效率至關重要。
使用Python集合類別處理資料
Python提供了多種內建的資料結構,如列表、字典、集合等,以支援不同的資料處理需求。在本章中,我們將探討如何使用Python的集合類別(set)以及其他相關的資料結構,如defaultdict和Counter,來有效地處理和分析資料。
使用生成器運算式處理貨幣資料
在處理貨幣資料時,我們可能需要從一個包含多個列表的列表中提取特定的資訊。例如,給定一個名為currencies的列表,其中每個內部列表包含一個國家的貨幣名稱和其對應的三字母程式碼。
currencies = [
['Afghan Afghani (AFN)', 'AFN'],
['Albanian Lek (ALL)', 'ALL'],
['Algerian Dinar (DZD)', 'DZD']
]
內容解密:
- 生成器運算式:我們可以使用生成器運算式來提取貨幣名稱或程式碼。生成器運算式是一種簡潔的方式來建立序列。
- 列表推導式:透過將生成器運算式放在
[]中,我們可以建立一個新的列表。 dict()函式:將列表轉換為字典,以便於根據鍵值查詢資料。
# 提取貨幣名稱
names = [name for name, code in currencies]
print(names)
# 建立貨幣程式碼到名稱的對映
codes = dict((code, name) for name, code in currencies)
print(codes)
內容解密:
- 使用列表推導式和生成器運算式可以簡潔有效地處理資料。
dict()函式用於建立字典,方便進行鍵值查詢。
使用defaultdict和Counter對映
Python的collections模組提供了defaultdict和Counter等類別,以支援更靈活的資料處理。
使用defaultdict統計雙字母序列
在密碼學分析中,瞭解文字中的雙字母序列(digrams)頻率是非常有用的。
from collections import defaultdict
corpus_file = "/usr/share/dict/words"
digram_count = defaultdict(int)
with open(corpus_file) as corpus:
for line in corpus:
word = line.lower().strip()
for position in range(len(word) - 1):
digram = word[position:position + 2]
digram_count[digram] += 1
內容解密:
defaultdict(int):當鍵不存在時,自動初始化為0,適合用於計數。- 檔案處理:讀取單詞檔案,並對每個單詞進行處理。
- 雙字母序列統計:對每個單詞,統計其雙字母序列的出現次數。
使用Counter類別
Counter類別是defaultdict(int)的一種特例,提供了更多的功能,如傳回最常見的元素。
from collections import Counter
digram_count = Counter()
# ... (與前述相同的處理邏輯)
print(digram_count.most_common(10))
內容解密:
Counter類別簡化了計數邏輯,並提供瞭如most_common()等實用方法。
使用Python集合
Python的集合(set)是一種無序、不重複元素的集合,適合用於成員測試和消除重複資料。
# 建立一個集合
unique_items = {1, 2, 3, 2, 1}
print(unique_items)
# 空集合的建立
empty_set = set()
print(empty_set)
內容解密:
- 集合語法:使用
{}建立集合,但空集合必須使用set()建立,以避免與字典混淆。 - 集合特性:集合中的元素是唯一的,且無序。
透過上述介紹,我們可以看到Python提供的多種資料結構和工具如何有效地支援不同型別的資料處理和分析任務。無論是使用生成器運算式處理複雜資料,還是利用defaultdict和Counter進行靈活的計數統計,或是使用集合進行成員測試和去重,Python都為我們提供了強大而靈活的解決方案。
集合處理與資料分析
在處理資料時,集合(set)是一種非常有用的資料結構。集合是一種無序且不重複的資料集合,可以用來進行快速的成員檢查和集合運算。
使用集合處理連字元詞
在分析一組文字資料時,我們可能會遇到一些包含連字元的詞彙。以下是一個簡單的範例,展示如何使用集合來找出這些詞彙:
corpus_file = "/usr/share/dict/words"
hyphenated = set()
with open(corpus_file) as corpus:
for line in corpus:
word = line.lower().strip()
if '-' in word:
hyphenated.add(word)
內容解密:
- 開啟檔案:首先開啟一個包含詞彙的檔案。
- 逐行讀取:讀取檔案中的每一行,並將其轉換為小寫並去除前後空白。
- 檢查連字元:檢查每個詞彙是否包含連字元,如果包含,則將其加入到
hyphenated集合中。 - 集合運算:使用集合來儲存連字元詞,避免重複詞彙。
使用 for 迴圈遍歷集合
在 Python 中,for 迴圈是遍歷集合的主要工具。以下是一個範例,展示如何使用 for 迴圈來遍歷一個列表或集合:
>>> for pounds in cheese:
... print(pounds)
...
29.87
etc.
33.51
內容解密:
- 遍歷列表:使用
for迴圈來遍歷cheese列表中的每個元素。 - 輸出元素:將每個元素輸出到控制檯。
處理列表中的元組
當處理包含元組的列表時,我們可以使用 for 迴圈來分解每個元組。以下是一個範例:
>>> for year, pounds in year_cheese:
... print(year, pounds)
...
2000 29.87
etc.
2012 33.51
內容解密:
- 分解元組:使用
for迴圈來分解year_cheese列表中的每個元組,將其分解為year和pounds兩個變數。 - 輸出結果:輸出每個元組的內容。
將計數轉換為百分比
在處理計數資料時,我們經常需要將計數轉換為百分比。以下是一個範例:
total = sum(digram_count.values())
for digram, count in digram_count.items():
print("{:2s} {:7d} {:.3%}".format(digram, count, count/total))
內容解密:
- 計算總數:計算
digram_count中的總計數。 - 遍歷專案:使用
for迴圈來遍歷digram_count中的每個專案。 - 輸出百分比:輸出每個專案的計數和百分比。
使用 Python 運算元處理集合
Python 中的一些數學運算元可以用來處理集合。以下是一些範例:
>>> {2, 3, 5, 7} | {5, 7, 11, 13, 17}
{2, 3, 5, 7, 11, 13, 17}
>>> {2, 3, 5, 7} & {5, 7, 11, 13, 17}
{5, 7}
>>> {2, 3, 5, 7} - {5, 7, 11, 13, 17}
{2, 3}
>>> {2, 3, 5, 7} ^ {5, 7, 11, 13, 17}
{2, 3, 11, 13, 17}
內容解密:
- 聯集:使用
|運算元來計算兩個集合的聯集。 - 交集:使用
&運算元來計算兩個集合的交集。 - 差集:使用
-運算元來計算兩個集合的差集。 - 對稱差集:使用
^運算元來計算兩個集合的對稱差集。
處理貨幣兌換率
在處理貨幣兌換率時,我們需要下載兌換率資料並將其轉換為可用的格式。以下是一個範例:
query_exchange_rates = "http://www.coinbase.com/api/v1/currencies/exchange_rates/"
with urllib.request.urlopen(query_exchange_rates) as document:
exchange_rates = json.loads(document.read().decode("utf-8"))
內容解密:
- 下載資料:使用
urllib.request.urlopen下載兌換率資料。 - 解析 JSON:使用
json.loads將下載的資料解析為 Python 物件。
處理兌換率資料
下載的兌換率資料是一個龐大的字典,我們需要將其轉換為可用的格式。以下是一個範例:
from collections import defaultdict
rates = defaultdict(list)
for conversion, rate in exchange_rates.items():
source, _, target = conversion.upper().partition("_TO_")
rates[source].append((target, float(rate)))
內容解密:
- 建立預設字典:使用
defaultdict建立一個預設字典來儲存兌換率資料。 - 遍歷兌換率:遍歷下載的兌換率資料,將其轉換為可用的格式。
- 儲存兌換率:將兌換率儲存到預設字典中。
使用Python進行智慧資料擷取與處理
在前一章中,我們探討瞭如何使用Python存取網路上的資料。本章節將探討如何使用Python進行影像處理以及利用隱寫術(Steganography)編碼秘密訊息。
處理貨幣匯率資料
首先,我們來看看如何處理貨幣匯率資料。我們使用defaultdict(list)來儲存匯率資料,這樣當某個鍵不存在時,會自動建立一個空列表作為其值。
from collections import defaultdict
# 假設raw_data是我們的原始資料
raw_data = {
'USD_TO_GBP': '0.76',
'USD_TO_EUR': '0.88',
# 更多匯率資料...
}
rates = defaultdict(list)
for conversion, rate in raw_data.items():
source, target = conversion.upper().partition('_TO_')[::2]
rate = float(rate)
rates[source].append((target, rate))
# 顯示特定貨幣的匯率
for c in ['USD', 'GBP', 'EUR']:
print(c, rates[c])
內容解密:
- 我們使用
defaultdict(list)來初始化rates變數,這樣可以避免鍵不存在的錯誤。 - 我們遍歷
raw_data中的每個轉換和匯率,將轉換字串轉換為大寫並分割成來源和目標貨幣。 - 將匯率從字串轉換為浮點數,以便後續計算。
- 將目標貨幣和匯率作為二元組新增到對應來源貨幣的列表中。
提升輸出可讀性
為了使輸出更加易讀,我們可以建立一個將貨幣程式碼對映到其全名的字典。
currency_details = {code: name for name, code in currencies}
for c in ['USD', 'GBP', 'EUR']:
print(currency_details[c], rates[c])
內容解密:
- 我們使用字典推導式來建立
currency_details字典,將貨幣程式碼對映到其全名。 - 遍歷特定的貨幣程式碼,列印出其全名和對應的匯率列表。
儲存資料
我們可以使用json.dump()將currency_details儲存到檔案中。
import json
with open('currency_details.json', 'w') as f:
json.dump(currency_details, f)
內容解密:
- 匯入
json模組。 - 開啟一個檔案用於寫入,並使用
json.dump()將currency_details字典儲存到檔案中。
影像處理與隱寫術
在下一章中,我們將探討如何使用Python處理影像檔案。我們將介紹Pillow函式庫,它為處理影像檔案提供了強大的工具。我們還將學習如何利用隱寫術在影像中編碼秘密訊息。
使用Pillow處理影像
要使用Python處理影像,我們需要安裝Pillow函式庫。Pillow是PIL(Python Imaging Library)的一個分支,它提供了豐富的影像處理功能。
from PIL import Image
# 開啟一個影像檔案
img = Image.open('example.jpg')
# 顯示影像資訊
print(img.format, img.size, img.mode)
內容解密:
- 從PIL匯入
Image模組。 - 使用
Image.open()開啟一個影像檔案。 - 列印出影像的格式、大小和模式。
隱寫術簡介
隱寫術是一種在看似無害的媒體(如影像)中隱藏秘密訊息的技術。我們將探討兩種常見的隱寫術演算法,並學習如何在Python中實作它們。
使用隱寫術編碼秘密訊息
在這一章中,我們將探討 Python 在處理各種檔案格式方面的強大能力,特別是在圖片檔案處理以及隱寫術的應用。首先,我們會回顧之前所學的技術,並進一步研究如何處理 CSV 檔案以及多種圖片檔案格式。
處理檔案格式的背景簡介
在前面的章節中,我們已經接觸到了多種檔案格式,例如 ZIP 檔案和 JSON 檔案。ZIP 檔案是一種壓縮檔案格式,可以包含多個檔案;而 JSON 檔案則用於序列化多種 Python 物件。在本章中,我們將重點關注圖片檔案的處理。
使用 OS 檔案系統
Python 提供了多個模組來處理檔案,主要使用 glob 和 os 模組。
glob 模組
glob 模組實作了檔案系統的 globbing 規則。當我們在終端機中使用 *.jpg 時,作業系統的 shell 工具會將這個萬用字元擴充套件成實際的檔案名稱列表。以下是一個例子:
MacBookPro-SLott:code slott$ ls *.jpg
1drachmi_1973.jpg IPhone_Internals.jpg
Common_face_of_one_euro_coin.jpg LHD_warship.jpg
在 Python 中,我們可以使用 glob.glob() 函式來實作相同的功能:
>>> import glob
>>> glob.glob("*.jpg")
['1drachmi_1973.jpg', 'Common_face_of_one_euro_coin.jpg', 'IPhone_Internals.jpg', 'LHD_warship.jpg']
os 模組
許多檔案具有 路徑/名稱.副檔名 的格式。在 Windows 中,路徑可能包含裝置字首和反斜線(例如 c:\路徑\名稱.副檔名)。Python 的 os.path 模組提供了多個函式,可以跨平台處理檔案名稱和路徑。以下是使用 os.path.splitext() 函式來分隔檔案名稱和副檔名的例子:
>>> import os
>>> os.path.splitext("1drachmi_1973.jpg")
('1drachmi_1973', '.jpg')
處理簡單的文字檔案
對於包含普通文字的檔案,我們可以使用以下方式開啟並處理每一行:
with open("some_file") as data:
for line in data:
# 處理每一行
pass
每一行都會包含一個尾隨的 \n 字元。我們可以使用生成器表示式來去除每一行的尾隨空白字元:
with open("some_file") as data:
clean_lines = (raw.rstrip() for raw in data)
for line in clean_lines:
# 處理每一行
pass
使用 ZIP 檔案
ZIP 壓縮檔包含一個或多個檔案。要使用 ZIP 壓縮檔,我們需要匯入 zipfile 模組:
import zipfile
內容解密:使用生成器表示式處理文字檔案
為什麼使用生成器表示式?
使用生成器表示式可以延遲處理,直到實際需要時才進行運算,從而提高效率。
生成器表示式的基本結構
生成器表示式由三部分組成:
- 子表示式(例如
raw.rstrip()) - 目標變數(例如
raw) - 來源可迭代集合(例如
data)
在上述例子中,每一行從 data 中被指定給 raw,然後執行子表示式 raw.rstrip(),最後將結果提供給外部的 for 迴圈。
多步驟處理
我們可以將多個生成器表示式串聯起來,以實作多步驟的資料清理。例如,先去除尾隨空白字元,再過濾掉空白行:
with open("some_file") as data:
clean_lines = (raw.rstrip() for raw in data)
non_blank_lines = (line for line in clean_lines if len(line) != 0)
for line in non_blank_lines:
# 處理每一行非空白且已清理的行
pass
這個方法允許我們將不同的設計考量分開,使程式碼更清晰、更易於維護。