为什么python代码运行不了_Python | 为什么优化代码?
通過優(yōu)化代碼來降低運(yùn)行時(shí)間是一件十分有意義的工作。然而,大部分情況下,優(yōu)化是編寫軟件的最后一個(gè)步驟,并且通常是在不得不優(yōu)化的情況下進(jìn)行的。如果你的代碼可以在能夠接受的時(shí)間范圍內(nèi)運(yùn)行完成,那么優(yōu)化并不是必需的。
鑒于此,為什么我們還要優(yōu)化代碼呢?作為數(shù)據(jù)科學(xué)家,我們現(xiàn)在面對(duì)的是越來越大規(guī)模的數(shù)據(jù)集,在每個(gè)元素上進(jìn)行的操作可能要重復(fù)數(shù)十億次才能得到最后的結(jié)果。如果代碼質(zhì)量很低,可能需要花費(fèi)數(shù)天才能完成運(yùn)行。此外,大部分科學(xué)計(jì)算和數(shù)值軟件是計(jì)算密集型而不是網(wǎng)絡(luò)密集型的任務(wù)。鑒于數(shù)據(jù)計(jì)算中使用的模型也越來越復(fù)雜,每一點(diǎn)的性能下降都會(huì)產(chǎn)生嚴(yán)重的后果。那么優(yōu)化代碼還有什么其他的原因嗎?原因如下。時(shí)間就是金錢:如果你是在云端運(yùn)行程序,那么時(shí)間就是金錢。額外的每一分鐘處理都需要付費(fèi),當(dāng)程序在數(shù)千臺(tái)機(jī)器上的時(shí)候更是如此。而且要注意的是,Amazon EC2是按小時(shí)計(jì)費(fèi),而不是像Google Compute Engine那樣按分鐘計(jì)費(fèi)。這就意味著在EC2上運(yùn)行61分鐘要比運(yùn)行59分鐘多出一倍的費(fèi)用。
迭代次數(shù):循環(huán)次數(shù),或者是在指定截止日前迭代的次數(shù)是另一個(gè)十分重要的問題。如果你的分析程序需要一個(gè)星期才能運(yùn)行出結(jié)果,那么你就無法像研究只需運(yùn)行24小時(shí)的程序那樣,不斷解析每次迭代過程的結(jié)果,中斷運(yùn)行,更新結(jié)果。相信我,你不可能在第一次甚至第三次都得到完美的分析。多輪迭代十分重要。
生產(chǎn)部署要求:生產(chǎn)環(huán)境對(duì)代碼運(yùn)行的時(shí)間有更高的要求。你的代碼能否實(shí)時(shí)給出結(jié)果?你的計(jì)算能否在用戶等厭煩而離開前給出結(jié)果?或者你的代碼是否需要批量地通宵運(yùn)行?是否有一個(gè)運(yùn)行完成的時(shí)間窗口?將你的代碼從原型轉(zhuǎn)化至批量上線運(yùn)行的過程中,執(zhí)行時(shí)間是一個(gè)十分重要的問題。
能耗節(jié)約:完成同樣的任務(wù),若可以使用調(diào)用更少指令、消耗更少的內(nèi)存和更少的CPU時(shí)間的代碼,會(huì)節(jié)省很多能源。如果你需要考慮移動(dòng)設(shè)備的能源消耗或者服務(wù)器的熱力性能,請(qǐng)優(yōu)化你的代碼。
為從大數(shù)據(jù)到大計(jì)算的轉(zhuǎn)換做準(zhǔn)備:現(xiàn)在這個(gè)時(shí)代是大數(shù)據(jù)的時(shí)代(對(duì)于一般的數(shù)據(jù)科學(xué)家來說,這和他們息息相關(guān)),一旦人們厭倦了統(tǒng)計(jì)點(diǎn)擊次數(shù)和簡(jiǎn)單的大規(guī)模分析,人們會(huì)開始進(jìn)行更多更有意思的計(jì)算。很快我們將從大數(shù)據(jù)時(shí)代進(jìn)入大計(jì)算時(shí)代,CPU時(shí)間將超過存儲(chǔ)和帶寬成為最寶貴的資源。到那時(shí),代碼優(yōu)化將成為極其重要的一個(gè)環(huán)節(jié),高性能計(jì)算(HPC)領(lǐng)域的工作將逐漸成為主流。
樂趣以及個(gè)人提高:從代碼中榨取出更多的性能是個(gè)十分有意思的謎題。這需要你極其深入地了解所使用的編程語言(了解語言作者對(duì)語言核心部分的設(shè)計(jì)),并且在極端情況下需要了解底層硬件的能力和限制。現(xiàn)如今,高級(jí)語言有各種內(nèi)建的庫和框架來幫助你處理幾乎所有的事情,很少有人擁有對(duì)語言這種深度的理解。
了解優(yōu)化的步驟
本小節(jié)將簡(jiǎn)要介紹軟件優(yōu)化的步驟。
處理流程
下面的內(nèi)容介紹了我們將要使用的代碼優(yōu)化步驟。
1.建立現(xiàn)有代碼的基線性能(執(zhí)行時(shí)間、內(nèi)存消耗、峰值I/O帶寬等)。
2.確定性能目標(biāo)以及系統(tǒng)的上限。以終為始是高效能人士的七個(gè)習(xí)慣之一,優(yōu)化也是同樣的道理。代碼需要執(zhí)行多快?完成任務(wù)可接受的最長(zhǎng)時(shí)間是多少?軟件最大可以占用多少內(nèi)存?計(jì)算結(jié)果需要多準(zhǔn)確?結(jié)果需要怎樣的保真度?
3.建立測(cè)試和度量環(huán)境,可以幫助你迅速測(cè)量相關(guān)的性能指標(biāo)。如果能夠更容易地度量每一行代碼的性能,那么就可以更快地優(yōu)化代碼。如果度量的過程十分痛苦并且總要去記一些你會(huì)忘記的命令,優(yōu)化的過程就會(huì)變得痛苦而緩慢。
4.記錄當(dāng)前代碼的所有參數(shù)和狀態(tài)快照。
5.利用剖析器尋找代碼瓶頸。
6.從最主要的瓶頸入手來解決性能問題。鑒于代碼的復(fù)雜度,每輪測(cè)試只解決一個(gè)問題是一種安全的方法。
7.利用剖析器分析修改后的代碼,檢查結(jié)果是否有變化。
8.跳回第4步,盡可能多地重復(fù)進(jìn)行。
工作原理
和粉刷房屋一樣,你需要做好充足的準(zhǔn)備才能取得成功。在刷子觸碰到墻壁前,你需要挪走墻邊的所有家具并給它們蓋上布。地板通常被一塊干布保護(hù)起來。畫、架子和其他掛載在墻上的一些東西都必須取下來,釘子也必須拔掉。還需要用濕布擦拭墻來除掉灰塵,并處理那些需要修補(bǔ)的地方。接下來,你需要封住那些不需要被粉刷的部分,如門邊、窗邊、電源插座。所有這些都做好后,真正粉刷墻只需要花很少的時(shí)間。優(yōu)化也和這個(gè)過程類似,你必須創(chuàng)建好一個(gè)利于優(yōu)化進(jìn)行的環(huán)境。因此上面的第3步“建立測(cè)試和度量環(huán)境”是十分重要的一步。
在優(yōu)化代碼的過程中,你會(huì)不斷停下來測(cè)試大大小小的代碼變更。一些工作正常,一些會(huì)使代碼無法工作。一些會(huì)提高性能,而另一些不會(huì)。當(dāng)你不斷停下來進(jìn)行測(cè)試時(shí),能夠恢復(fù)四五次之前性能最好的可工作代碼變得異常重要。同樣重要的是,要記住每次變更所帶來的性能影響。當(dāng)你測(cè)試了一組代碼變化后,你需要知道保留哪些變化。Git、Mercurial 和其他一些代碼版本管理工具都是你的好幫手。
在第6步中,這種處理瓶頸的順序通常是從簡(jiǎn)至難。如果主要的瓶頸需要重寫大量的代碼才能解決,那么可以先去解決那些只需要一行代碼或者很少的變更即可解決的次要性能瓶頸。
更多內(nèi)容
每一行可能帶來性能提升的代碼同樣可能引入新的問題。因此在優(yōu)化代碼時(shí),不要去做和優(yōu)化性能無關(guān)的事情。最糟糕的優(yōu)化可能會(huì)帶來難以檢測(cè)的問題,甚至代碼行為的不一致。同樣需要注意的是,優(yōu)化代碼的過程可能會(huì)使你自己和需要接手代碼的人越來越難讀懂代碼。
識(shí)別代碼中常見性能瓶頸
在優(yōu)化數(shù)據(jù)科學(xué)項(xiàng)目的過程中,查看整個(gè)分析過程、了解每個(gè)階段所需要消耗的時(shí)間以及它們之間的關(guān)系是十分重要的。
讓我們把問題簡(jiǎn)化成減少軟件的執(zhí)行時(shí)間,且只考慮使用一種特定的語言來實(shí)現(xiàn)這個(gè)軟件。在這里,我們不考慮處理大數(shù)據(jù)集,也就是說,將數(shù)據(jù)規(guī)模從生產(chǎn)數(shù)據(jù)庫規(guī)模降到簡(jiǎn)單分析用的數(shù)據(jù)。
從更抽象的層次來說,執(zhí)行時(shí)間只和代碼本身以及硬件條件相關(guān)。如果想要降低運(yùn)行時(shí)間,要么修改代碼,要么升級(jí)硬件,或者兩者同時(shí)進(jìn)行。
對(duì)于優(yōu)化來說,我們必須時(shí)刻記住自己的目的是什么:必須達(dá)到何種程度的優(yōu)化或者軟件需要運(yùn)行多快。
將運(yùn)行時(shí)間降為原來的二分之一和降低一個(gè)數(shù)量級(jí)是兩種完全不同的優(yōu)化方式,通常后者需要代碼發(fā)生根本性的變化。
處理流程
剖析器(一種可以提供其他軟件運(yùn)行時(shí)信息的軟件)可以幫助你找到運(yùn)行最慢的代碼行或者代碼塊。通過觀察,你可以發(fā)現(xiàn)存在某種特定的代碼類型、代碼模式或者問題域,可以提高代碼的速度。
1.留心任何的循環(huán),尤其是嵌套循環(huán)。嵌套的層次越多,代碼通常越慢。
2.注意那些運(yùn)行速度慢的數(shù)學(xué)操作,如平方根、三角函數(shù)以及除加減之外的其他運(yùn)算。
3.減小關(guān)鍵數(shù)據(jù)結(jié)構(gòu)的大小。
4.選擇經(jīng)常使用的變量的精度(float、double、int、uint8等)。
5.避免無用的運(yùn)算。
6.簡(jiǎn)化數(shù)學(xué)方程式。
工作原理
第一步要檢查循環(huán),因?yàn)檠h(huán)中的代碼將會(huì)執(zhí)行多次,如果有循環(huán)嵌套,那么執(zhí)行的次數(shù)又會(huì)大幅上升。那些被反復(fù)執(zhí)行的代碼是性能優(yōu)化的過程中需要重點(diǎn)關(guān)注的地方。此外,對(duì)于R和Matlab等一些特定領(lǐng)域語言,語言的特性導(dǎo)致它們的循環(huán)性能很差。在這種情況下,用另一種編程結(jié)構(gòu)(R里的函數(shù)編程方式或者M(jìn)atlab的向量化表達(dá)方法)代替循環(huán)會(huì)帶來性能的提升。
在第二步中,對(duì)于計(jì)算密集型任務(wù),通過定位計(jì)算緩慢的數(shù)學(xué)操作,通常能發(fā)現(xiàn)顯著提高執(zhí)行速度的機(jī)會(huì)。自然界中存在大量的現(xiàn)象需要用平方根來解釋,如常見的計(jì)算n維空間內(nèi)兩點(diǎn)間歐氏距離。不幸的是,求平方根的操作開銷很大,相比于基本的加減乘除以及邏輯判斷,求平方根的操作要慢很多。而乘除相比于加減和邏輯判斷也要慢很多。
一般來說,你手上的T1-85或者HP 48G計(jì)算器上,除了加、減、乘、除按鈕,其他數(shù)學(xué)函數(shù)都要遠(yuǎn)遠(yuǎn)慢于這4個(gè)基本操作。這就意味著你必須考慮如下函數(shù)。cos:余弦
sin:正弦
tan:正切
acos:反余弦
asin:反正弦
atan:反正切
exp:冪運(yùn)算
pow:以10為底的對(duì)數(shù)
ln:自然對(duì)數(shù)
cosh:雙曲余弦
sinh:雙曲正弦
tanh:雙曲正切
acosh:反雙曲余弦
asinh:反雙曲正弦
atanh:反雙曲正切
之前計(jì)算兩點(diǎn)間距離的代碼中大量使用了條件判斷語句,如下面的代碼。
if distance_between(point1, point2) > 1.0 ...
或者將代碼寫得更直接一些:
if square_root( (x1-x2)^2 + (y1-y2)^2 ) > 1.0 ...
這時(shí)優(yōu)化的機(jī)會(huì)就出現(xiàn)了:如果在不等式兩端都做平方,那么開銷昂貴的求平方根方法就可以被去除了。但是需要考慮平方根的一些特性,以及在1、?1和0上的平方操作。平方的過程中,負(fù)數(shù)會(huì)變成正數(shù),小數(shù)會(huì)更接近零。當(dāng)處理距離和其他一些物理量時(shí),負(fù)數(shù)通常都不是一個(gè)問題。
作為一個(gè)通用的法則,數(shù)據(jù)結(jié)構(gòu)越小,計(jì)算速度越快。越小的數(shù)據(jù)結(jié)構(gòu),越能很好地利用分層的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)越接近CPU。理想情況下,所有的計(jì)算數(shù)據(jù)都已經(jīng)存儲(chǔ)在寄存器上,無須從L1、L2甚至更低的緩存中獲取,更不要說去系統(tǒng)內(nèi)存中獲取,否則會(huì)導(dǎo)致速度明顯下降。而面向?qū)ο蟮恼Z言通常在這方面有缺陷。每個(gè)數(shù)據(jù)結(jié)構(gòu)都必須綁定很多無須用到的方法,導(dǎo)致數(shù)據(jù)結(jié)構(gòu)變大,以至于不得不在每次迭代過程中從系統(tǒng)內(nèi)存中獲取數(shù)據(jù)。
從技術(shù)上來說,第四步可以減小數(shù)據(jù)的體積,但是這也需要針對(duì)具體情況來分析。一些語言默認(rèn)設(shè)置整數(shù)和浮點(diǎn)數(shù)都為64位。對(duì)于一些整數(shù)來說,并不需要64位這么大的空間。事實(shí)上,大部分情況下,8位的整數(shù)就可以滿足一般需求。有些時(shí)候不需要表示負(fù)數(shù)時(shí),無符號(hào)整數(shù)是一個(gè)更優(yōu)的選擇。
很多浮點(diǎn)數(shù)的計(jì)算事實(shí)上不需要如此高的精度。16位的整數(shù)可不可以?32位的整數(shù)可不可以?通過這種方式可以將數(shù)據(jù)體積降為原來的二分之一或者四分之一,并帶來明顯的性能提升。
對(duì)于第五步,尋找那些可以在分支中執(zhí)行的代碼,尤其是需要大量計(jì)算的代碼。如果一個(gè)昂貴的運(yùn)算并不是總要去執(zhí)行,那么把它放入一個(gè)分支中,只在必要的時(shí)候運(yùn)行。
在編寫計(jì)算復(fù)雜的代碼時(shí),大部分代碼都寫得很簡(jiǎn)單明了,使得作者可以一次就得到正確的結(jié)果。這就意味著可能會(huì)有一些不必要的復(fù)雜計(jì)算、速度慢的代碼存在,尤其是在條件判斷附近。如果你使用的是編譯型語言,編譯器可能會(huì)對(duì)代碼進(jìn)行重新排列,但是最好還是不要過于依賴它(動(dòng)態(tài)語言和JVM上運(yùn)行的語言,在運(yùn)行期很難判斷它們究竟會(huì)做什么)。
對(duì)于第六步,大部分?jǐn)?shù)學(xué)表達(dá)式寫出來都是給人看的,而不是為了讓現(xiàn)代計(jì)算機(jī)軟件和硬件可以很好地運(yùn)行。簡(jiǎn)單修改一下等式,去除一些項(xiàng)或者改寫一些項(xiàng)都會(huì)帶來性能的提升。例如,將乘法轉(zhuǎn)為加法,除法轉(zhuǎn)為乘法。對(duì)于那些需要執(zhí)行上億的操作來說,這些小小的改動(dòng)會(huì)帶來時(shí)間上巨大的節(jié)省。加減預(yù)算要快于乘法,而乘法又要快于除法。
通讀代碼
我們將要優(yōu)化的是一段計(jì)算分子可接觸表面積(Accessible Surface Area,ASA)的 Python代碼。ASA量化了分子可以被溶液所接觸的表面面積,這是一個(gè)在生物和生物化學(xué)中廣泛使用的量值。對(duì)于本小節(jié)來說,你不需要對(duì)ASA有十分深入的了解。如果你對(duì)此很有興趣,強(qiáng)烈推薦你看一下Bosco K.Ho關(guān)于ASA的博客和代碼。他也是本小節(jié)中原始代碼的作者。代碼出于清晰和正確的目的,并沒有過多考量性能。
出于優(yōu)化的目的,代碼將被集成在一個(gè)網(wǎng)頁應(yīng)用中。當(dāng)用戶上傳數(shù)據(jù)時(shí),分子的ASA將會(huì)被計(jì)算。由于所有計(jì)算過程都是同步的,代碼執(zhí)行時(shí)間越長(zhǎng),用戶等待時(shí)間越久。
本小節(jié),我們將閱讀代碼 asa.py源文件中的核心部分,對(duì)代碼進(jìn)行一個(gè)大概的了解,并發(fā)現(xiàn)潛在的性能瓶頸。
準(zhǔn)備工作
在文本編輯器或者IDE中打開asa.py文件。這個(gè)文件中包含的代碼可以在本書的代碼庫中找到。
處理流程
下面的步驟將會(huì)帶你瀏覽我們將要優(yōu)化的代碼。工作原理部分將詳細(xì)介紹代碼是如何工作的。
1.在文本編輯器中瀏覽asa.py。注意哪些包被導(dǎo)入、哪些函數(shù)被定義,閱讀代碼中的注釋。
2.移動(dòng)到main()函數(shù),瀏覽之后一連串的函數(shù)調(diào)用。思考main()函數(shù)在asa.py中的作用是什么。
3.深入閱讀每個(gè)函數(shù),從最重要的calculate_asa函數(shù)開始。
工作原理
asa.py的main()函數(shù)處理包含需要被分析的分子信息的文件及其他命令行參數(shù)。當(dāng)利用 molecule.py中的方法導(dǎo)入分子結(jié)構(gòu)后,再調(diào)用calculate_asa函數(shù)來處理之后的所有計(jì)算。
在文件的頂端,找到第一個(gè)函數(shù)generate_sphere_points(),這個(gè)函數(shù)可以計(jì)算在指定半徑范圍內(nèi)的等距點(diǎn)的個(gè)數(shù),并將等距點(diǎn)以三元組列表的形式返回。
該函數(shù)利用螺旋黃金分割算法來生成平面上的等距點(diǎn)。此外,還有幾種不同的方法來處理同樣的問題(在參考資料一節(jié)會(huì)給出相應(yīng)鏈接)。點(diǎn)的個(gè)數(shù)是這個(gè)函數(shù)唯一的參數(shù),這些點(diǎn)用來表示一個(gè)表面。越多的點(diǎn)數(shù),越能精確地表現(xiàn)這個(gè)表面。如果函數(shù)接受無數(shù)個(gè)點(diǎn),那么就可以完美地表示這個(gè)表面。
讓我們從一些細(xì)節(jié)入手性能優(yōu)化。點(diǎn)的列表在初始化時(shí)為空,每輪迭代都會(huì)在尾部插入新的點(diǎn)。在快速寫代碼的過程中,體積不斷增長(zhǎng)的數(shù)據(jù)結(jié)構(gòu)通常會(huì)導(dǎo)致嚴(yán)重的問題。
其次,range(int(n))產(chǎn)生了一個(gè)有int(n)個(gè)元素的列表,元素的值為0至int(n) ? 1。這種情況下,需要在內(nèi)存中分配整個(gè)擁有n個(gè)元素列表的內(nèi)存空間。當(dāng)n很大時(shí),需要消耗大量時(shí)間進(jìn)行內(nèi)存分配。最好利用生成器的方式完成此類工作,比如用xrange函數(shù)代替range函數(shù)。xrange只需要分配一個(gè)xrange對(duì)象的內(nèi)存空間,并且只在真正需要一個(gè)值的時(shí)候生成一個(gè)數(shù)字。此外,xrange是用純C語言實(shí)現(xiàn)的。這些是針對(duì)3.0版本前的Python。3.0版本后,range實(shí)現(xiàn)為一個(gè)迭代器。
最后也是最重要的一件事是,Python的for循環(huán)對(duì)性能消耗很大。我們希望能夠把循環(huán)從解釋器中移除,利用編譯后的C代碼來實(shí)現(xiàn)。
find_neighbor_indices函數(shù)接收3個(gè)參數(shù)。atoms:分子中的原子列表;
probe:探針的距離,通常設(shè)為1.4;
k:我們需要為k原子找到鄰近原子。
這個(gè)函數(shù)返回在特定原子探針距離內(nèi)的原子索引的列表。
代碼中有一個(gè)遍歷所有索引的循環(huán)。在循環(huán)內(nèi)部,neighbor_indices變量隨迭代不斷增長(zhǎng),vector3d.py中的pos_distance函數(shù)不斷被調(diào)用。在函數(shù)中,我們看到首先計(jì)算兩點(diǎn)p1和p2的距離的平方,然后取平方根的操作,如下面的代碼所示。
def pos_distance(p1, p2):
return math.sqrt(pos_distance_sq(p2, p1))
def pos_distance_sq(p1, p2):
x = p1.x - p2.x
y = p1.y - p2.y
z = p1.z - p2.z
return x*x + y*y + z*z;
注意,math.sqrt函數(shù)是個(gè)計(jì)算開銷十分大的函數(shù)。
calculate_asa (atoms, probe, n_sphere_point=960)函數(shù)是主要的工作函數(shù),用來處理和協(xié)調(diào)相關(guān)的計(jì)算。它接受3個(gè)參數(shù)。atoms:分子中的原子列表;
probe:探針的距離,通常設(shè)為1.4;
n_sphere_point:用來近似表示一個(gè)表面所用到的等距點(diǎn)的個(gè)數(shù)(越多的等距點(diǎn)表示越精準(zhǔn),也越耗時(shí))。
最重要的一個(gè)參數(shù)是用來計(jì)算ASA的原子列表。每個(gè)原子都有x、y、z三個(gè)坐標(biāo)和一個(gè)相關(guān)的半徑。Atom類在molecule.py文件中被定義。
函數(shù)一開始通過generate_sphere_points生成一組表面的點(diǎn)并初始化空列表。接下來是一個(gè)三層循環(huán),最外層的循環(huán)遍歷原子列表中的所有原子,對(duì)于一個(gè)典型的分子來說可能會(huì)有上百甚至上千個(gè)原子。在這一層for循環(huán)中,對(duì)于每個(gè)原子調(diào)用find_neighbor_indices來生成最鄰近的原子列表。
接下來進(jìn)入第二層循環(huán),遍歷sphere_points中的每一個(gè)點(diǎn)。如果使用默認(rèn)的960個(gè)節(jié)點(diǎn),那么循環(huán)將有960次迭代。對(duì)于平面等距點(diǎn)結(jié)合中的每一個(gè)點(diǎn),我們加入當(dāng)前原子的中心坐標(biāo)。
然后就是最內(nèi)層循環(huán),遍歷所有的鄰近原子。對(duì)于每個(gè)鄰近原子,我們比較test_point到鄰近原子中心的距離。如果兩點(diǎn)之間在一個(gè)特定的距離內(nèi),我們就認(rèn)為test_point不能被溶劑分子接觸。
用另一種方式來解釋,內(nèi)部?jī)蓪友h(huán)利用預(yù)先生成好的表面等距點(diǎn)生成測(cè)試原子。然后檢查每個(gè)點(diǎn),看看是否存在有一個(gè)鄰近原子在指定的距離內(nèi)。如果存在,那么表面上的這個(gè)點(diǎn)就被認(rèn)為是不可被接觸的。
原子的可接觸區(qū)域即為被鄰近節(jié)點(diǎn)所阻斷的原子周圍表面部分。
三層嵌套循環(huán)和大量的計(jì)算意味著有很大的性能提升空間。
參考資料最早的ASA計(jì)算相關(guān)的論文:Environment and exposure to solvent of protein atoms. Lysozyme and insulin, A. Shrake, J.A. Rupley. J Mol Biol 79 (2): 351–71. doi:10.1016/0022-2836(73)90011-9。
本文節(jié)選自《數(shù)據(jù)科學(xué)實(shí)戰(zhàn)手冊(cè)》(R+Python)
這本書是基于R和Python的數(shù)據(jù)科學(xué)項(xiàng)目案例集錦,內(nèi)容涵蓋了基于數(shù)據(jù)科學(xué)的所有要素,包括數(shù)據(jù)采集、處理、清洗、分析、建模、可視化以及數(shù)據(jù)產(chǎn)品的搭建。案例包含了汽車數(shù)據(jù)分析、股票市場(chǎng)建模、社交網(wǎng)絡(luò)分析、推薦系統(tǒng)、地理信息分析,以及Python代碼的計(jì)算優(yōu)化。通過手把手的案例解析,令讀者知其然并知其所以然。
業(yè)界的數(shù)據(jù)分析師、數(shù)據(jù)挖掘工程師、數(shù)據(jù)科學(xué)家都可以讀一讀。想要了解實(shí)際工作中如何用數(shù)據(jù)產(chǎn)生價(jià)值的在校學(xué)生,或者對(duì)數(shù)據(jù)科學(xué)感興趣的人也值得一讀。
從本書中你將學(xué)會(huì)什么?了解數(shù)據(jù)科學(xué)的路徑,并且?guī)椭鶰ac、Windows和Linux操作系統(tǒng)的讀者恰當(dāng)?shù)卮罱〝?shù)據(jù)科學(xué)環(huán)境。
對(duì)汽車數(shù)據(jù)進(jìn)行分析和可視化,從中發(fā)現(xiàn)不同時(shí)間燃料效率的變化趨勢(shì)和模式。
模擬美式橄欖球比賽數(shù)據(jù)(R)
讀者展示如何搭建自己的選股系統(tǒng),并且使用移動(dòng)平均法分析股票歷史數(shù)據(jù)。
就業(yè)數(shù)據(jù)的可視化探索(R)。向讀者展示如何從勞動(dòng)統(tǒng)計(jì)局獲取雇傭和收入數(shù)據(jù),并且用R對(duì)不同水平的數(shù)據(jù)進(jìn)行空間分析。
運(yùn)用稅務(wù)數(shù)據(jù)進(jìn)行應(yīng)用導(dǎo)向的數(shù)據(jù)分析(Python)。向讀者展示如何使用Python將自己的分析從一次性臨時(shí)的工作轉(zhuǎn)變?yōu)榭蓮?fù)用的產(chǎn)品化的代碼。這些工作都是基于一份收入數(shù)據(jù)展開。
運(yùn)用汽車數(shù)據(jù)進(jìn)行可視化分析(Python)這里使用的是強(qiáng)大的編程語言Python。
社交網(wǎng)絡(luò)分析(Python),向讀者展示如何建立、可視化和分析社交網(wǎng)絡(luò)。
大規(guī)模電影推薦(Python)。告訴你如何用Python搭建電影推薦系統(tǒng)。
獲取和定位Twitter數(shù)據(jù)(Python)。向讀者展示如何調(diào)用Twitter的API獲取Twitter用戶數(shù)據(jù),并繪制用戶信息中包含的地理信息數(shù)據(jù)。
利用NumPy和SciPy優(yōu)化數(shù)值計(jì)算(Python)。帶領(lǐng)讀者領(lǐng)略如何優(yōu)化Python代碼,從而在處理大數(shù)據(jù)集時(shí)節(jié)省時(shí)間和金錢。
總結(jié)
以上是生活随笔為你收集整理的为什么python代码运行不了_Python | 为什么优化代码?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 对Airtest报告的步骤标题做内容定制
 - 下一篇: PhpStorm编辑器-MAC快捷键