小內(nèi)存服務(wù)器與大數(shù)據(jù):如何避免內(nèi)存浪費

一 起因
起因嘛,非常簡單。最近自己要復(fù)現(xiàn)一個作者(20年,16G內(nèi)存)的算法來分析一個已發(fā)表的數(shù)據(jù),竟然發(fā)現(xiàn)64G的內(nèi)存不夠用。不行,肯定得折騰,于是,就有下面的推文
Ps:還是建議大家擁有足夠的內(nèi)存使用空間,不用這么畏首畏尾,胡亂折騰。
二?正文
為方便演示,我先展示一段代碼
肯定有讀者想要問這段代碼是什么意思。bingo,就交給ChatGPT吧!

這段代碼的作用是生成隨機數(shù)據(jù),并將其轉(zhuǎn)換為 Pandas 數(shù)據(jù)框,然后使用 Pandas 對數(shù)據(jù)框進行操作和合并,最終計算并輸出每組數(shù)據(jù)在元組('condition_A', 'condition_B', 'fold')的平均表現(xiàn)。
具體步驟如下:
1:定義一個空字典 result,用于存儲每組數(shù)據(jù)在不同的條件和折疊次數(shù)下的數(shù)據(jù)框。
2:定義一個列表 cycle_list,其中包含了 20 組條件,每組條件包括三個整數(shù)值:a、b 和 c,它們分別等于 1+unit_x、30+unit_x 和 60+unit_x,其中 unit_x 取值從 0 到 19。
3:對于每組條件,生成一個具有大量隨機數(shù)據(jù)的 NumPy 數(shù)組 data,其中數(shù)組的行數(shù)根據(jù)公式計算得出,每行包含 10 個隨機數(shù)。
4:將 NumPy 數(shù)組 data 轉(zhuǎn)換為 Pandas 數(shù)據(jù)框 df。
5:將 Pandas 數(shù)據(jù)框 df 作為值,以元組 (a, b, c) 作為鍵,添加到字典 result 中。
6:將字典 result 中的所有數(shù)據(jù)框按照元組 (a, b, c)?進行拼接,并以這三個條件為索引,得到一個大的 Pandas 數(shù)據(jù)框 result_merge。
7:在 Pandas 數(shù)據(jù)框 result_merge 中,根據(jù)元組 (a, b, c)?對得分列 score 進行分組,并計算每組的平均值,得到一個 Pandas 序列 performance。
總的來說,這段代碼主要是用于生成大量的隨機數(shù)據(jù),并對這些數(shù)據(jù)進行 Pandas 操作和合并,以實現(xiàn)對數(shù)據(jù)的快速處理和分析。
2.1 代碼重構(gòu)
首先,我們拿這一段代碼來說,第一個問題出現(xiàn)在下面這段代碼中
我們發(fā)現(xiàn)這一段代碼中最主要的問題出現(xiàn)在后面的result_merge變量僅僅需要使用到score標簽的數(shù)值,然而,代碼的這一步環(huán)節(jié),卻生成了兩個變量
因此,我們需要改變的地方就是在這
2.2 改變精度
我們接著會發(fā)現(xiàn),其中內(nèi)存占用較高的原因是因為這個變量
這里每一步都會產(chǎn)生約4G的內(nèi)存使用量。那么我們該如何改變這個現(xiàn)象了,這里就得提到python數(shù)據(jù)精度的問題了。默認情況下,python的浮點精度是float64,但是這一浮點精度是可以調(diào)整到float32。因此,我們可以將代碼修改成這樣,直接減少一半的內(nèi)存使用量
需要注意的是,這一步的實施其實是有代價的。這會犧牲數(shù)據(jù)的精度,對于結(jié)果也會有一些細微的影響,但是,如果在短時間內(nèi)我們無法提高數(shù)據(jù)內(nèi)存容量的時候,并且確定自己數(shù)據(jù)中大部分內(nèi)容的精度是低于float32的時候,我們就可以采用這一方法
2.3?及時釋放內(nèi)存
需要注意的,有時候某些步驟的運算可能也是特別耗內(nèi)存的,比如下面這一步。我們假設(shè)在某個斷點,在result_merge變量未生成的時候,這一步,pd.concat其實一直在消耗著內(nèi)存,占用存儲空間。即在原變量保持不變的環(huán)境下,新的臨時變量一直在占用內(nèi)存
此時,我們可以通過以下函數(shù)實現(xiàn)最小內(nèi)存空間的占用
我們通過循環(huán)的方式,避免了一次生成大的變量,并且在新變量不斷變大的過程中,我們通過del和gc命令,減少原變量的內(nèi)存使用量,避免了兩個變量同時擠占內(nèi)存,有效減少了內(nèi)存的動態(tài)使用。這一步也可以理解成為以時間換空間吧。
三?慣例小結(jié)
雖然,我們通過改變作者的代碼實現(xiàn)低內(nèi)存下運行一些之前需要兩到三倍內(nèi)存的數(shù)據(jù),但是這往往需要犧牲精度或者時間。即使原作者的代碼的確有很大的改進空間(的確可能會有),我們通常也不會輕易變動(除非讀者有信息熟讀代碼,了解整體的代碼框架)。因為誰知道你一改會不會結(jié)果有較大偏差了呢?
所以,最好的情況是擁有足夠的資源,可以使用作者的源代碼跑出結(jié)果。如果這種情況滿足不了的話,那只能筆者一樣了(手動狗頭)。
四 公眾號其他資源(方便讀者使用)
本公眾號開發(fā)的相關(guān)軟件,Multi-omics Hammer軟件和Multi-omics Visual軟件歡迎大家使用。
Multi-omics Hammer軟件下載地址:
https://github.com/wangjun258/Multi-omics-Hammer
Multi-omics Visual軟件下載地址:https://github.com/wangjun258/Multi_omics_Visual/releases/tag/Multi_omics_Visual_v1.03
PS:因為本軟件是用python腳本撰寫,調(diào)用了部分依賴包,用戶首次使用需要安裝python以及對應(yīng)的包,安裝之后便可永久使用。
下面是本號在其他平臺的賬戶,也歡迎大家關(guān)注并多提意見。
簡書:WJ的生信小院
公眾號:生信小院
博客園:生信小院
最后,也歡迎各位大佬能夠在本平臺上:1傳播和講解自己發(fā)表的論文;2:發(fā)表對某一科研領(lǐng)域的看法;3:想要達成的合作或者相應(yīng)的招聘信息;4:展示自己以尋找博后工作或者博士就讀的機會;5:博導(dǎo)提供博后工作或者博士攻讀機會,都可以后臺給筆者留言。希望本平臺在進行生信知識分享的同時,能夠成為生信分析者的交流平臺,能夠?qū)崿F(xiàn)相應(yīng)的利益互補和雙贏(不一定能實現(xiàn),但是夢想總得是有的吧)。
五 每日一圖(源自Stable-diffuse創(chuàng)作)?



