生命科學學生的WSL與Python學習之旅 (第二集)

更新 發佈閱讀 10 分鐘

成功在Windows Subsystem for Linux中,建立了Python環境、安裝必須的工具,並解決許多軟硬體的問題之後,我正式展開了我使用Python進行生物資訊分析的新篇章。

然而,上次的難題才剛解決沒有多久,還來不及迎接下一個突發狀況時,新的挑戰就如排山倒海般地淹來;而這次的意外,甚至直接造成整個WSL系統強制登出,導致分析作業被迫中斷。但是,水能覆舟,亦能載舟;它有時是發生災難,讓我心痛不已的系統,有時卻又是意外發揮功用,拯救我分析事業的系統。這中間的故事,容我為各位娓娓道來。

還沒看過第一集的,這裡有:【連結


第一個難題:與記憶體的戰爭 – t-SNE視覺化的挑戰

t-隨機鄰近嵌入法(t-distributed Stochastic Neighbor Embedding),是一種非線性的降維技術,其主要應用在高維度數據的視覺化;以生物的資料而言,每個基因都是一個維度、每個樣本也是一個維度;當同時分別有幾萬筆基因與樣本時,就有成千上萬個維度,構成我們大腦難以直接理解的「高維度數據」。

這時候如果套用t-SNE,就能透過這種降維技術,將高維度的資訊「濃縮」到一張我們更容易理解的二維(或三維)平面圖上;降維的同時,這套方法也會高精度地保留重要的訊息,使得原本就比較相像的兩個樣本能彼此靠近;原本差異就比較大的細胞則相距較遠。這樣,我們就能初步解開癌細胞之間複雜的交互作用與模式,並使用它畫出來的二維圖表給我們帶來新的啟發。後續也可以透過演算法,查出是哪些基因造成癌症種類中的差異。

我在五月的實作中,繪製好的t-SNE圖

我在五月的實作中,繪製好的t-SNE圖

然而,這些高維度的資料,通常資料上的大小也非常可觀。各位可以想像如果你有一張幾萬列、幾萬行的Excel表格,然後要一次記得所有數字,同時計算它們之間的差異,一定是不可能的事情。當我們沒辦法將新的資訊放入短期記憶區,就會很有壓力,處理事情的效率也會下降;電腦也一樣,會因為記憶體過滿,導致它沒辦法再記憶新的表格內容或其他系統程序,整個系統就這樣當機了

當時我並沒有留意到這點。我以為一份5.2 GB的表格檔案,讀進Pandas dataframe裡面也應該要是同樣的記憶體使用量,沒有想過Pandas會建立索引值(會造成額外記憶體開銷)來記憶表格的內容。於是,原本我只分配給我的WSL系統6GB的記憶體,就在短短的幾分鐘內消耗殆盡(註一),甚至系統程序沒辦法執行,因此WSL直接強制關機。

那時候我急了,因為我的筆電也沒辦法再裝更多的實體記憶體,於是我只能想辦法透過虛擬記憶體(註二)的方式,試圖用.wslconfig檔案(如下圖)內的設定,拆儲存空間的東牆、補記憶體的西牆來拯救這場危機。

.wslconfig的示例;當中swap即為虛擬記憶體空間,可以MB或GB當作單位

.wslconfig的示例;當中swap即為虛擬記憶體空間,可以MB或GB當作單位

我從10 GB、20 GB、一路嘗試到90 GB的虛擬記憶體,記憶體不足的問題才終於緩解;只是因為虛擬記憶體是建立在儲存空間中,一般會比實體記憶體慢很多,所以我守在電腦旁邊,一整個晚上過去了,程式碼還是執行中;讀完整個資料框了,但是卡在「將所有資料預處理」的過程。

最後,我只好跟 ChatGPT 講這件事情,請它來救救我;它提示我可以分批次讀取整個檔案,每讀完一個區塊就使用列表記下來(更省記憶體)再繼續讀取下一個部分,就不會有記憶體問題。另外也推薦給我比csv格式更有效率的parquet檔案格式(註三)。

分批次讀取的邏輯,大致如下(Python):

import pandas as pd
chunk_list = []

# 分批讀取檔案
for chunk in pd.read_csv('large_file.tsv', sep='\t', chunksize=10000):
processed_chunk = process(chunk) # 假設的資料處理函數
chunk_list.append(processed_chunk)

# 合併所有分批處理過的資料
final_df = pd.concat(chunk_list)

我霎時一驚:這些不就是我之前寫40 GB以上的資料庫時用過的技巧嗎?於是我就決定先採用分批讀取的思維試試看。結果,同樣一臺電腦,它只花用十幾分鐘就讀取csv表格完畢,而只佔據大約16 GB記憶體。

經過這次事件,我發現因為WSL如果未另外安裝某些程式的話,就不會有類似Windows 工作管理員的使用者介面,可以隨時監控記憶體用量,於是往後就建立起習慣,跑程式前、運行時都用free -h指令來檢查記憶體用量,以及虛擬記憶體的配置是否正確等;另外也學會利用分批次讀取的思維面對大型的表格,而不是直接整個讀取。

若在Linux的終端機中執行watch -n 5 free -h,即可輸出類似下圖的記憶體整理:

raw-image

第二個難題:Windows下載生物資訊大型檔案失敗,改用WSL的命令列下載

實做生物資訊的人們,免不了要利用國外公開的資料庫來找到有用的資訊,這當中就包含美國的「癌症基因組圖譜」 (The Cancer Genome Atlas, TCGA) 。最一開始,我試著使用在Windows底下安裝的Google Chrome瀏覽器來下載壓縮檔,但是解壓縮時卻發生了「災難性的錯誤」,移到WSL中利用解壓縮的指令運行則是發現了「tar: 未預期的封存結尾 (Unexpected EOF)」。

這時候用WSL中的ls -lh指令看這份檔案的大小,發現網站上寫這份壓縮檔有412 MB,但是下載下來的壓縮檔只有74 MB。一看到這點,再加上下載檔案速度真的很慢,我就懷疑應該是連線逾時導致瀏覽器沒辦法給我完整的檔案。

於是,這個時候我從美國國家癌症研究所 (National Cancer Institute, NCI) 上找到了他們提供的命令列工具:GDC Data Transfer Tool並在WSL中安裝;然後改用manifest格式檔案作為該程式判斷下載檔案的依據。

注意:以下是bash指令,且WSL中安裝的是Ubuntu 24.04 LTS。

cd ~
wget https://gdc.cancer.gov​/files/public/file/gdc-client_v1.6.1_Ubuntu_x64.zip
unzip gdc-client_v1.6.1_Ubuntu_x64.zip
chmod +x gdc-client

./gdc-client download -m manifest.txt -d ~/blca​

這樣,當我從TCGA上面擷取到BLCA癌症的manifest檔案時,它就會自己從資料庫下載這些資料到我指定的~/blca資料夾中!

不過,有時候事情總是一波未平、一波又起;在我使用這些指令下載資料的時候,命令列突然出現了104: ECONNRESET,而且還是好幾十筆資料都因為這樣而無法下載,變成之後我要用wget來補。

問過ChatGPT之後,讓我有了新的發現:很多人都跟我遇到過一樣的問題,但原因很簡單:像是TCGA這種美國的國家級資料庫,幾乎都有預防駭客攻擊的機制,例如防止分散式阻斷服務攻擊 (Distributed Denial-of-Service, DDoS) 的防火牆來預防伺服器崩潰,一旦遇到有人使用數十或數百個連線來下載檔案,即認定是攻擊而自動重設連線。

而GDC Data Transfer Tool 預設是開啟許多個連線下載這些檔案,這在一個終端機分頁中倒是還好;但是如果同時開很多個終端機做一樣的事情(只是換成不同的癌症種類)就恰好達到「數十或數百個連線」的阻斷條件,於是資料就因為連線重置而無法正常下載。

知道這些之後,我只能乖乖地把分頁關到只剩下一個,並且補上-t 1的指令讓它一個檔案只開一條連線;用慢慢下載的策略來防止連線被重置。這次還是有104: ECONNRESET,但是機率大幅減少,要用wget補上的功夫也就省下了一大半。

對我而言,WSL這次的神救援無疑又給我上了幾堂寶貴的課程:如何冷靜地判斷應該採用的策略,而不是卡在瀏覽器下載失敗的問題本身;以及網路層的安全機制與共處技巧。


下集預告:WSL的大搬家!正式移轉至原生Ubuntu 24.04系統的兩大挑戰

如果喜歡這個系列,請喜歡這篇文章;每一個喜歡,都是我繼續分享這些故事的動力。

(註一)
WSL的預設設定會占用Windows一半的實體記憶體;當時我在Windows端裝有12 GB的記憶體,因此系統判定分配 6 GB。

(註二)
在我的這篇案例中,虛擬記憶體是透過「用磁碟空間來擴充實體記憶體」來實現的;如果要看更多介紹,詳見:維基百科

(註三,本註解由 Google Gemini 生成)
Parquet是一種欄式儲存格式(Columnar Storage Format),主要用於在大數據處理和分析中儲存和查詢數據。 它是一種高效的檔案格式,相對於傳統的行式儲存格式(Row-based Storage),可以更有效地進行壓縮和讀取特定欄位,其通常被用於各種大數據處理框架。

留言
avatar-img
生資知識的道場
6會員
16內容數
歡迎來到【生資道場】! 這裡是一個結合生物資訊與生活思維的小宇宙。 我們聊癌症、談程式碼,也偶爾思考世界的複雜與美感。 不一定要懂程式、不一定要是科研人, 只要你對知識、生活與實驗感興趣,就能自在入座。 歡迎留言交流,理性討論,偶爾隨著道場主一起激盪新想法。
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
牽涉到的工具:wsl2 + anaconda + jupyter-nootbook
Thumbnail
牽涉到的工具:wsl2 + anaconda + jupyter-nootbook
Thumbnail
在離線環境需要安裝Python套件時就相當的麻煩,需要先下載好套件包,在打指令安裝,若套件數量一多時就會相當麻煩。 本文將介紹如何利用兩行指令快速的安裝整個資料夾的套件。
Thumbnail
在離線環境需要安裝Python套件時就相當的麻煩,需要先下載好套件包,在打指令安裝,若套件數量一多時就會相當麻煩。 本文將介紹如何利用兩行指令快速的安裝整個資料夾的套件。
Thumbnail
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
Thumbnail
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
Thumbnail
如何用Python將DataFrame中的資料擷取維新的DataFrame?
Thumbnail
如何用Python將DataFrame中的資料擷取維新的DataFrame?
Thumbnail
本文在介紹如何用Python繪製各點大小不同的散布圖及用箭頭標註特殊點
Thumbnail
本文在介紹如何用Python繪製各點大小不同的散布圖及用箭頭標註特殊點
Thumbnail
本文介紹如何用Python繪製散布圖與迴歸線
Thumbnail
本文介紹如何用Python繪製散布圖與迴歸線
Thumbnail
如何用Python匯入大批Excel檔案? os.listdir建立資料夾內[檔案名稱.副檔名]之列表 利用迴圈將所有檔案匯入Python 用pandas.concat合併所有DataFrame
Thumbnail
如何用Python匯入大批Excel檔案? os.listdir建立資料夾內[檔案名稱.副檔名]之列表 利用迴圈將所有檔案匯入Python 用pandas.concat合併所有DataFrame
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News