返回文章列表

命令列工具資料處理技巧

本文介紹如何使用命令列工具進行資料處理,涵蓋從不同來源(例如 Excel、關聯式資料函式庫和 Web API)擷取和處理資料,以及如何將單行命令轉換為可重複使用的 Shell 指令碼,提升資料處理效率。

資料科學 資料工程

在資料科學專案中,有效率地處理資料至關重要。利用命令列工具,能以簡潔且強大的方式操作各種資料格式和來源。從 Excel 試算表轉換為 CSV 檔案、查詢關聯式資料函式庫、呼叫 Web API 取得 JSON 資料,到將常用的單行命令封裝成 Shell 指令碼,都能大幅提升資料處理的效率和可重複性。這些工具的組合運用,讓資料科學家和工程師能更專注於資料分析和模型建立,而無需耗費過多時間在繁瑣的資料處理流程上。

使用命令列工具處理資料

在資料科學領域中,取得和處理資料是至關重要的步驟。許多資料來源於不同的格式,如CSV、Excel試算表、關聯式資料函式庫和網路API。本篇文章將介紹如何使用命令列工具來處理這些資料來源。

將Microsoft Excel試算表轉換為CSV

Microsoft Excel是一種常見的試算表格式,但不是所有工具都能直接處理Excel檔案。幸運的是,有一個名為in2csv的命令列工具,可以將Excel試算表轉換為CSV格式。

使用in2csv轉換Excel檔案

首先,下載一個Excel檔案,例如荷蘭年度廣播電台節目Top 2000的歌曲排行榜:

$ curl "https://www.nporadio2.nl/data/download/TOP-2000-2020.xlsx" > top2000.xlsx

接著,使用in2csv將Excel檔案轉換為CSV:

$ in2csv top2000.xlsx | tee top2000.csv | trim
NR.,ARTIEST,TITEL,JAAR
1,Danny Vera,Roller Coaster,2019
2,Queen,Bohemian Rhapsody,1975
3,Eagles,Hotel California,1977
4,Billy Joel,Piano Man,1974
5,Led Zeppelin,Stairway To Heaven,1971
6,Pearl Jam,Black,1992
7,Boudewijn de Groot,Avond,1997
8,Coldplay,Fix You,2005
9,Pink Floyd,Wish You Were Here,1975

篩選特定藝術家的歌曲

使用csvgrep篩選出特定藝術家的歌曲,例如Queen:

$ csvgrep top2000.csv --columns ARTIEST --regex '^Queen$' | csvlook -I
│ NR. │ ARTIEST │ TITEL │ JAAR │
├──────┼─────────┼─────────────────────────────────┼──────┤
2 │ Queen │ Bohemian Rhapsody │ 197511 │ Queen │ Love Of My Life │ 197546 │ Queen │ Innuendo │ 199155 │ Queen │ Don't Stop Me Now │ 197970 │ Queen │ Somebody To Love │ 197685 │ Queen │ Who Wants To Live Forever │ 198689 │ Queen │ The Show Must Go On │ 1991131 │ Queen │ Killer Queen │ 1974

內容解密:

  • in2csv:將Excel檔案轉換為CSV格式。
  • csvgrep:根據指定的欄位和正規表示式篩選CSV檔案中的資料。
  • --columns ARTIEST:指定要篩選的欄位為ARTIEST
  • --regex '^Queen$':使用正規表示式篩選出ARTIEST欄位中值為Queen的行。
  • csvlook:以表格形式顯示CSV資料。

從關聯式資料函式庫查詢資料

許多公司將資料儲存在關聯式資料函式庫中。可以使用sql2csv工具從命令列查詢這些資料函式庫。

使用sql2csv查詢SQLite資料函式庫

假設有一個名為r-datasets.db的SQLite資料函式庫,其中包含一個名為mtcars的表格。可以使用以下命令查詢該表格並按mpg欄位排序:

$ sql2csv --db 'sqlite:///r-datasets.db' \
> --query 'SELECT row_names AS car, mpg FROM mtcars ORDER BY mpg' | csvlook
│ car │ mpg │
├─────────────────────┼──────┤
│ Cadillac Fleetwood │ 10.4 │
│ Lincoln Continental │ 10.4 │
│ Camaro Z28 │ 13.3 │
│ Duster 360 │ 14.3 │
│ Chrysler Imperial │ 14.7 │
│ Maserati Bora │ 15.0 │
│ Merc 450SLC │ 15.2 │
│ AMC Javelin │ 15.2 │

內容解密:

  • sql2csv:從關聯式資料函式庫查詢資料並輸出為CSV格式。
  • --db 'sqlite:///r-datasets.db':指定要查詢的SQLite資料函式庫檔案。
  • --query 'SELECT ...':指定要執行的SQL查詢。
  • csvlook:以表格形式顯示查詢結果。

呼叫網路API

許多網站提供網路API,用於以結構化的格式(如JSON或XML)提供資料。可以使用命令列工具如curljq來處理這些API傳回的資料。

使用curljq處理JSON資料

例如,呼叫Ice and Fire API來取得角色Jon Snow的資訊:

$ curl -s "https://anapioficeandfire.com/api/characters/583" | jq '.'
{
"url": "https://anapioficeandfire.com/api/characters/583",
"name": "Jon Snow",
"gender": "Male",
"culture": "Northmen",
"born": "In 283 AC",
"died": "",
"titles": [
"Lord Commander of the Night's Watch"
],
"aliases": [
"Lord Snow",
"Ned Stark's Bastard",
"The Snow of Winterfell",
"The Crow-Come-Over",
"The 998th Lord Commander of the Night's Watch",
"The Bastard of Winterfell",

內容解密:

  • curl -s "https://anapioficeandfire.com/api/characters/583":呼叫API取得Jon Snow的資訊。
  • jq '.':使用jq解析傳回的JSON資料並美化輸出。

使用命令列工具存取Web API

在資料科學和軟體開發領域,存取Web API以取得資料是一項基本技能。命令列工具提供了一種高效、靈活的方式來與Web API進行互動。本文將介紹如何使用命令列工具存取Web API,包括處理身份驗證、流式資料以及使用諸如curljq等工具來操作和解析傳回的資料。

取得API資料

首先,我們需要了解如何使用curl命令來取得API的資料。考慮到一個簡單的例子,使用curl存取一個公開的API:

curl -s "https://anapioficeandfire.com/api/characters/583" | jq .

內容解密:

  • curl是一個用於在命令列下工作的工具,用於與伺服器進行資料傳輸。
  • -s引數代表「silent mode」,抑制進度表和其他不必要的輸出。
  • https://anapioficeandfire.com/api/characters/583是目標API的URL。
  • jq .用於漂亮地列印JSON輸出,使其更易於閱讀。

身份驗證

許多API需要身份驗證才能存取。News API就是一個例子,它要求使用API金鑰:

curl -s "http://newsapi.org/v2/everything?q=linux&apiKey=$(< /data/.secret/newsapi.org_apikey)" | jq '.'

內容解密:

  • &apiKey=$(< /data/.secret/newsapi.org_apikey)是將API金鑰附加到URL的查詢引數中。
  • $(< file)是一種命令替換,用於讀取檔案/data/.secret/newsapi.org_apikey的內容作為API金鑰。

流式API

有些API會以流式方式傳回資料,例如Twitter的「fire hose」或Wikimedia的變更流:

curl -s "https://stream.wikimedia.org/v2/stream/recentchange" | sample -s 10 > wikimedia-stream-sample

內容解密:

  • sample -s 10是一個命令列工具,用於在10秒後關閉連線,取得樣本資料。
  • > wikimedia-stream-sample將輸出重定向到檔案wikimedia-stream-sample

處理流式資料

對於流式傳回的資料,可以使用sedjq等工具進行處理:

< wikimedia-stream-sample sed -n 's/^data: //p' | jq 'select(.type == "edit" and .server_name == "en.wikipedia.org") | .title'

內容解密:

  • sed -n 's/^data: //p'用於處理Wikimedia流輸出的資料,只列印預以data:開頭的行,並移除data:字首。
  • jq 'select(.type == "edit" and .server_name == "en.wikipedia.org") | .title'進一步過濾JSON資料,只選擇型別為「edit」且伺服器名稱為「en.wikipedia.org」的物件,並輸出其.title值。

將單行命令轉換為可重複使用的命令列工具

在處理資料科學任務時,經常會遇到需要重複執行某些命令或一連串命令的情況。將這些命令轉換為可重複使用的命令列工具(Command-Line Tools),不僅可以提高工作效率,還能讓你的資料科學工具箱更加豐富。

為什麼要建立命令列工具?

命令列工具具有以下幾個優點:

  1. 提高效率:無需每次都輸入完整的命令,可以直接呼叫工具。
  2. 改善可讀性:將複雜的命令或程式碼封裝成工具後,可以使你的工作流程更加清晰易懂。
  3. 增加靈活性:透過新增引數,可以使工具適應不同的任務需求。

將單行命令轉換為 Shell 指令碼

假設我們需要取得一段文字中最常出現的前 10 個單詞。以下是一個實作該功能的單行命令:

curl -sL "https://www.gutenberg.org/files/11/11-0.txt" |
tr '[:upper:]' '[:lower:]' |
grep -oE "[a-z\']{2,}" |
sort |
uniq -c |
sort -nr |
head -n 10

這個命令的流程是:

  1. 使用 curl 下載電子書。
  2. 使用 tr 將文字轉換為小寫。
  3. 使用 grep 提取單詞。
  4. 使用 sortuniq -c 統計每個單詞的出現次數。
  5. 使用 sort -nr 按次數降序排列。
  6. 使用 head -n 10 取得前 10 個最常出現的單詞。

內容解密:

  1. curl -sL "https://www.gutenberg.org/files/11/11-0.txt":下載指定的電子書。-sL 引數用於靜默模式下載並跟隨重定向。
  2. tr '[:upper:]' '[:lower:]':將所有大寫字母轉換為小寫字母,以便進行大小寫不敏感的單詞統計。
  3. grep -oE "[a-z\']{2,}":使用正規表示式提取單詞。-o 引數表示只輸出匹配的部分,-E 啟用擴充套件正規表示式。
  4. sort:對單詞進行排序,為統計做準備。
  5. uniq -c:統計每個單詞的出現次數。-c 引數表示計數。
  6. sort -nr:按計數結果降序排序。-n 表示按數字排序,-r 表示逆序。
  7. head -n 10:輸出前 10 行結果,即出現次數最多的前 10 個單詞。

將單行命令轉換為 Shell 指令碼

為了使這個命令更加通用和可重複使用,我們可以將其轉換為一個 Shell 指令碼,並新增必要的引數,使其能夠接受不同的輸入和引數設定。

#!/bin/bash

# 定義指令碼功能描述
echo "Usage: $0 [-n number] [-f file_url]"
echo "  -n number: Number of top words to display (default: 10)"
echo "  -f file_url: URL of the text file to process (default: Alice's Adventures in Wonderland)"

# 解析命令列引數
while getopts ":n:f:" opt; do
  case $opt in
    n) num_top_words="$OPTARG"
    ;;
    f) file_url="$OPTARG"
    ;;
    \?) echo "Invalid option -$OPTARG"; exit 1
    ;;
  esac
done

# 設定預設值
num_top_words=${num_top_words:-10}
file_url=${file_url:-"https://www.gutenberg.org/files/11/11-0.txt"}

# 執行資料處理流程
curl -sL "$file_url" |
tr '[:upper:]' '[:lower:]' |
grep -oE "[a-z\']{2,}" |
sort |
uniq -c |
sort -nr |
head -n "$num_top_words"

內容解密:

  1. while getopts ":n:f:" opt; do:使用 getopts 解析命令列引數。:n:f: 指定了兩個可接受的選項:-n-f,每個選項後面都需要跟一個引數值。
  2. num_top_words=${num_top_words:-10}:設定變數 num_top_words 的預設值為 10,如果使用者沒有提供 -n 引數,則使用此預設值。
  3. file_url=${file_url:-"https://www.gutenberg.org/files/11/11-0.txt"}:同樣地,設定 file_url 的預設值,用於指定要處理的文字檔案 URL。

將單行命令轉換為Shell指令碼

在命令列工具的開發過程中,將單行命令轉換為可重用的Shell指令碼是一個重要的步驟。這不僅提高了命令的靈活性,也使得命令的重用性大大增強。本篇文章將介紹如何將一個用於統計文字中詞頻的單行命令轉換為Shell指令碼。

原始單行命令

首先,我們來看一下原始的單行命令:

curl -sL "https://www.gutenberg.org/files/11/11-0.txt" |
tr '[:upper:]' '[:lower:]' |
grep -oE "[a-z\']{2,}" |
sort |
grep -Fvwf stopwords |
uniq -c |
sort -nr |
head -n 10

這個命令的目的是下載一個文字檔案,將其轉換為小寫,提取單詞,去除停用詞,統計詞頻,並輸出前10個最頻繁的單詞。

步驟1:建立檔案

首先,我們需要將這個單行命令複製到一個新的檔案中。可以使用任何文字編輯器,或者使用命令列工具如nanovim

$ fc

這將開啟預設的文字編輯器(在Docker容器中是nano),並且已經包含了最後執行的命令。

內容解密:

  • fc命令用於編輯最後執行的命令。
  • nano編輯器中,可以透過按Ctrl-O來儲存檔案。

步驟2:儲存檔案

nano編輯器中,按Ctrl-O,然後輸入檔名top-words-1.sh,最後按Enter儲存檔案。

File Name to Write: top-words-1.sh

內容解密:

  • 副檔名.sh表示這是一個Shell指令碼。
  • 儲存檔案後,可以使用bat命令來檢視檔案的內容。

步驟3:確認檔案內容

使用bat命令檢視剛剛建立的檔案的內容:

$ bat top-words-1.sh
───────┬────────────────────────────────────────────────────────────────────────
│ File: top-words-1.sh
───────┼────────────────────────────────────────────────────────────────────────
1 │ curl -sL "https://www.gutenberg.org/files/11/11-0.txt" |
2 │ tr '[:upper:]' '[:lower:]' |
3 │ grep -oE "[a-z\']{2,}" |
4 │ sort |
5 │ grep -Fvwf stopwords |
6 │ uniq -c |
7 │ sort -nr |
8 │ head -n 10
───────┴────────────────────────────────────────────────────────────────────────

內容解密:

  • bat命令用於以彩色格式顯示檔案內容。
  • 檔案內容與原始的單行命令一致。

步驟4:執行檔案

使用bash命令來執行這個Shell指令碼:

$ bash top-words-1.sh
403 alice
98 gutenberg
88 project
76 queen
71 time
63 king
60 turtle
57 mock
56 hatter
55 gryphon

內容解密:

  • bash命令用於執行Shell指令碼。
  • 指令碼輸出了文字中最頻繁的10個單詞。