日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

我是一個(gè)程序員。從大學(xué)時(shí)代開始我就一直在進(jìn)行編程,而我仍然對(duì)使用簡(jiǎn)單的Python代碼所開辟的道路之多感到驚訝。

但是我并不總是那么高效。我相信這是大多數(shù)程序員(尤其是剛起步的程序員)共有的一個(gè)特征,編寫代碼的快感始終優(yōu)先于效率和簡(jiǎn)潔性。雖然這在我們的大學(xué)期間有效,但在專業(yè)環(huán)境中,尤其是在數(shù)據(jù)科學(xué)項(xiàng)目中,情況卻大相徑庭。

優(yōu)化Python代碼的4種方法

 

作為數(shù)據(jù)科學(xué)家,編寫優(yōu)化的Python代碼非常非常重要。雜亂,效率低下的代碼即浪費(fèi)你的時(shí)間甚至浪費(fèi)你項(xiàng)目的錢。經(jīng)驗(yàn)豐富的數(shù)據(jù)科學(xué)家和專業(yè)人員都知道,當(dāng)我們與客戶合作時(shí),雜亂的代碼是不可接受的。

因此,在本文中,我將借鑒我多年的編程經(jīng)驗(yàn)來(lái)列出并展示四種可用于優(yōu)化數(shù)據(jù)科學(xué)項(xiàng)目中Python代碼的方法。

優(yōu)化是什么?

首先定義什么是優(yōu)化。我們將使用一個(gè)直觀的示例進(jìn)行此操作。

這是我們的問題:

假設(shè)給定一個(gè)數(shù)組,其中每個(gè)索引代表一個(gè)城市,該索引的值代表該城市與下一個(gè)城市之間的距離。假設(shè)我們有兩個(gè)索引,我們需要計(jì)算這兩個(gè)索引之間的總距離。簡(jiǎn)單來(lái)說(shuō),我們需要找到兩個(gè)給定索引之間距離的總和。

優(yōu)化Python代碼的4種方法

 


優(yōu)化Python代碼的4種方法

 

首先想到的是,一個(gè)簡(jiǎn)單的FOR循環(huán)在這里可以很好地工作。但是,如果有100,000多個(gè)城市,而我們每秒接收50,000多個(gè)查詢,該怎么辦?你是否仍然認(rèn)為FOR循環(huán)可以為我們的問題提供足夠好的解決方案?

FOR循環(huán)并不能提供足夠好的方案。這時(shí)候優(yōu)化就派上用場(chǎng)了

簡(jiǎn)單地說(shuō),代碼優(yōu)化意味著在生成正確結(jié)果的同時(shí)減少執(zhí)行任何任務(wù)的操作數(shù)。

讓我們計(jì)算一下FOR循環(huán)執(zhí)行此任務(wù)所需的操作數(shù):

優(yōu)化Python代碼的4種方法

 

我們必須在上面的數(shù)組中找出索引1和索引3的城市之間的距離。

優(yōu)化Python代碼的4種方法

 

對(duì)于較小的數(shù)組大小,循環(huán)的性能良好

如果數(shù)組大小為100,000,查詢數(shù)量為50,000,該怎么辦?

優(yōu)化Python代碼的4種方法

 

這是一個(gè)很大的數(shù)字。如果數(shù)組的大小和查詢數(shù)量進(jìn)一步增加,我們的FOR循環(huán)將花費(fèi)大量時(shí)間。你能想到一種優(yōu)化的方法,使我們?cè)谑褂幂^少數(shù)量的解決方案時(shí)可以產(chǎn)生正確的結(jié)果嗎?

在這里,我將討論一個(gè)更好的解決方案,通過使用前綴數(shù)組來(lái)計(jì)算距離來(lái)解決這個(gè)問題。讓我們看看它是如何工作的:

優(yōu)化Python代碼的4種方法

 


優(yōu)化Python代碼的4種方法

 


優(yōu)化Python代碼的4種方法

 

你能理解嗎?我們只需一次操作就可以得到相同的距離!關(guān)于此方法的最好之處在于,無(wú)論索引之間的差是1還是100,000,都只需執(zhí)行一個(gè)操作即可計(jì)算任意兩個(gè)索引之間的距離。

我創(chuàng)建了一個(gè)樣本數(shù)據(jù)集,其數(shù)組大小為100,000和50,000個(gè)查詢。你可以自己執(zhí)行代碼來(lái)比較兩者所用的時(shí)間

注意:數(shù)據(jù)集總共有50,000個(gè)查詢,你可以更改參數(shù)execute_queries以執(zhí)行最多50,000個(gè)查詢,并查看每種方法執(zhí)行任務(wù)所花費(fèi)的時(shí)間。

import time
from tqdm import tqdm
data_file = open('sample-data.txt', 'r')
distance_between_city = data_file.readline().split()
queries = data_file.readlines()
print('SIZE OF ARRAY = ', len(distance_between_city))
print('TOTAL NUMBER OF QUERIES = ', len(queries))
data_file.close()
# 分配要執(zhí)行的查詢數(shù)
execute_queries = 2000
print('nnExecuting',execute_queries,'Queries')
# FOR循環(huán)方法
# 讀取文件并存儲(chǔ)距離和查詢
start_time_for_loop = time.time()
data_file = open('sample-data.txt', 'r')
distance_between_city = data_file.readline().split()
queries = data_file.readlines()
# 存儲(chǔ)距離的列表
distances_for_loop = []
# 計(jì)算開始索引和結(jié)束索引之間的距離的函數(shù)
def calculateDistance(startIndex, endIndex):
 distance = 0
 for number in range(startIndex, endIndex+1, 1):
 distance += int(distance_between_city[number])
 return distance
for query in tqdm(queries[:execute_queries]):
 query = query.split()
 startIndex = int(query[0])
 endIndex = int(query[1])
 distances_for_loop.Append(calculateDistance(startIndex,endIndex))
data_file.close()
# 獲取結(jié)束時(shí)間
end_time_for_loop = time.time()
print('nnTime Taken to execute task by for loop :', (end_time_for_loop-start_time_for_loop),'seconds')
# 前綴數(shù)組方法
# 讀取文件并存儲(chǔ)距離和查詢
start_time_for_prefix = time.time()
data_file = open('sample-data.txt', 'r')
distance_between_city = data_file.readline().split()
queries = data_file.readlines()
# 存儲(chǔ)距離列表
distances_for_prefix_array = []
# 創(chuàng)建前綴數(shù)組
prefix_array = []
prefix_array.append(int(distance_between_city[0]))
for i in range(1, 100000, 1):
 prefix_array.append((int(distance_between_city[i]) + prefix_array[i-1]))
for query in tqdm(queries[:execute_queries]):
 query = query.split()
 startIndex = int(query[0])
 endIndex = int(query[1])
 if startIndex == 0:
 distances_for_prefix_array.append(prefix_array[endIndex])
 else:
 distances_for_prefix_array.append((prefix_array[endIndex]-prefix_array[startIndex-1]))
data_file.close()
end_time_for_prefix = time.time()
print('nnTime Taken by Prefix Array to execute task is : ', (end_time_for_prefix-start_time_for_prefix), 'seconds')
# 檢查結(jié)果
correct = True
for result in range(0,execute_queries):
 if distances_for_loop[result] != distances_for_prefix_array[result] :
 correct = False
if correct:
 print('nnDistance calculated by both the methods matched.')
else:
 print('nnResults did not matched!!')

(注:英文原文的代碼可以直接運(yùn)行,在文章末尾有英文原文的鏈接)

結(jié)果極大的節(jié)省了時(shí)間,這就是優(yōu)化Python代碼的重要性。我們不僅節(jié)省時(shí)間,而且還可以節(jié)省很多計(jì)算資源!

你可能想知道這些如何應(yīng)用于數(shù)據(jù)科學(xué)項(xiàng)目。你可能已經(jīng)注意到,很多時(shí)候我們必須對(duì)大量數(shù)據(jù)點(diǎn)執(zhí)行相同的查詢。在數(shù)據(jù)預(yù)處理階段尤其如此。

我們必須使用一些優(yōu)化的技術(shù)而不是基本的編程來(lái)盡可能快速高效地完成工作。因此,這里我將分享一些我用來(lái)改進(jìn)和優(yōu)化Python代碼的最佳技術(shù)

1. Pandas.apply() | 特征工程的鉆石級(jí)函數(shù)

Pandas已經(jīng)是一個(gè)高度優(yōu)化的庫(kù),但是我們大多數(shù)人仍然沒有充分利用它。現(xiàn)在你思考一下在數(shù)據(jù)科學(xué)中會(huì)使用它的常見地方。

我能想到的一項(xiàng)是特征工程,我們使用現(xiàn)有特征創(chuàng)建新特征。最有效的方法之一是使用Pandas.apply()。

在這里,我們可以傳遞用戶定義的函數(shù),并將其應(yīng)用于Pandas序列化數(shù)據(jù)的每個(gè)數(shù)據(jù)點(diǎn)。它是Pandas庫(kù)中最好的插件之一,因?yàn)榇撕瘮?shù)可以根據(jù)所需條件選擇性隔離數(shù)據(jù)。所以,我們可以有效地將其用于數(shù)據(jù)處理任務(wù)。

讓我們使用Twitter情緒分析數(shù)據(jù)來(lái)計(jì)算每條推文的字?jǐn)?shù)。我們將使用不同的方法,例如dataframe iterrows方法,NumPy數(shù)組和apply方法。你可以從此處下載數(shù)據(jù)集(https://datahack.analyticsvidhya.com/contest/practice-problem-twitter-sentiment-analysis/?utm_source=blog&utm_medium=4-methods-optimize-python-code-data-science)。

'''
優(yōu)化方法:apply方法
'''
# 導(dǎo)入庫(kù)
import pandas as pd 
import numpy as np
import time
import math
data = pd.read_csv('train_E6oV3lV.csv')
# 打印頭部信息
print(data.head())
# 使用dataframe iterows計(jì)算字符數(shù)
print('nnUsing Iterrowsnn')
start_time = time.time()
data_1 = data.copy()
n_words = []
for i, row in data_1.iterrows():
 n_words.append(len(row['tweet'].split()))
data_1['n_words'] = n_words 
print(data_1[['id','n_words']].head())
end_time = time.time()
print('nTime taken to calculate No. of Words by iterrows :',
(end_time-start_time),'seconds')
# 使用Numpy數(shù)組計(jì)算字符數(shù)
print('nnUsing Numpy Arraysnn')
start_time = time.time()
data_2 = data.copy()
n_words_2 = []
for row in data_2.values:
 n_words_2.append(len(row[2].split()))
data_2['n_words'] = n_words_2
print(data_2[['id','n_words']].head())
end_time = time.time()
print('nTime taken to calculate No. of Words by numpy array : ',
(end_time-start_time),'seconds')
# 使用apply方法計(jì)算字符數(shù)
print('nnUsing Apply Methodnn')
start_time = time.time()
data_3 = data.copy()
data_3['n_words'] = data_3['tweet'].apply(lambda x : len(x.split()))
print(data_3[['id','n_words']].head())
end_time = time.time()
print('nTime taken to calculate No. of Words by Apply Method : ',
(end_time-start_time),'seconds')

(注:英文原文的代碼可以直接運(yùn)行,在文章末尾有英文原文的鏈接,同上)

你可能已經(jīng)注意到apply方法比iterrows方法快得多。其性能可媲美與NumPy數(shù)組,但apply方法提供了更多的靈活性。你可以在此處閱讀apply方法的文檔。(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html)

2. Pandas.DataFrame.loc | Python數(shù)據(jù)處理的技巧

這是我最喜歡的Pandas庫(kù)的技巧之一。我覺得對(duì)于處理數(shù)據(jù)任務(wù)的數(shù)據(jù)科學(xué)家來(lái)說(shuō),這是一個(gè)必須知道的方法(所以幾乎每個(gè)人都是這樣!)

大多數(shù)時(shí)候,我們只需要根據(jù)某些條件來(lái)更新數(shù)據(jù)集中特定列的某些值。Pandas.DataFrame.loc為我們提供了針對(duì)此類問題的最優(yōu)化的解決方案。

讓我們使用loc函數(shù)解決一個(gè)問題。你可以在此處下載將要使用的數(shù)據(jù)集(https://drive.google.com/file/d/1VwXDA27zgx5jIq8C7NQW0A5rtE95e3XI/view?usp=sharing)。

# 導(dǎo)入庫(kù)
import pandas as pd
data = pd.read_csv('school.csv')
data.head()
優(yōu)化Python代碼的4種方法

 

檢查“City”變量的各個(gè)值的頻數(shù):

優(yōu)化Python代碼的4種方法

 

現(xiàn)在,假設(shè)我們只需要排名前5位的城市,并希望將其余城市替換為“Others”(其他)城市。因此,讓我們這么寫:

# 將熱門城市保存在列表中
top_cities = ['Brooklyn','Bronx','Manhattan','Jamaica','Long Island City']
# 使用loc更新目標(biāo)
data.loc[(data.City.isin(top_cities) == False),'City'] = 'Others'
# 各個(gè)城市的頻數(shù)
data.City.value_counts()
優(yōu)化Python代碼的4種方法

 

Pandas來(lái)更新數(shù)據(jù)的值是非常容易的!這是解決此類數(shù)據(jù)處理任務(wù)的最優(yōu)化方法。

3.在Python中向量化你的函數(shù)

擺脫慢循環(huán)的另一種方法是對(duì)函數(shù)進(jìn)行向量化處理。這意味著新創(chuàng)建的函數(shù)將應(yīng)用于輸入列表,并將返回結(jié)果數(shù)組。Python中的向量化可以加速計(jì)算

讓我們?cè)谙嗤腡witter Sentiment Analysis數(shù)據(jù)集對(duì)此進(jìn)行驗(yàn)證。

'''
優(yōu)化方法:向量化函數(shù)
'''
# 導(dǎo)入庫(kù)
import pandas as pd 
import numpy as np
import time
import math
data = pd.read_csv('train_E6oV3lV.csv')
# 輸出頭部信息
print(data.head())
def word_count(x) :
 return len(x.split())
# 使用Dataframe iterrows 計(jì)算詞的個(gè)數(shù)
print('nnUsing Iterrowsnn')
start_time = time.time()
data_1 = data.copy()
n_words = []
for i, row in data_1.iterrows():
 n_words.append(word_count(row['tweet']))
data_1['n_words'] = n_words 
print(data_1[['id','n_words']].head())
end_time = time.time()
print('nTime taken to calculate No. of Words by iterrows :',
(end_time-start_time),'seconds')
# 使用向量化方法計(jì)算詞的個(gè)數(shù)
print('nnUsing Function Vectorizationnn')
start_time = time.time()
data_2 = data.copy()
# 向量化函數(shù)
vec_word_count = np.vectorize(word_count)
n_words_2 = vec_word_count(data_2['tweet'])
data_2['n_words'] = n_words_2
print(data_2[['id','n_words']].head())
end_time = time.time()
print('nTime taken to calculate No. of Words by numpy array : ',
(end_time-start_time),'seconds')

難以置信吧?對(duì)于上面的示例,向量化速度提高了80倍!這不僅有助于加速我們的代碼,而且使其變得更整潔。

4. Python中的多進(jìn)程

多進(jìn)程是系統(tǒng)同時(shí)支持多個(gè)處理器的能力。

在這里,我們將流程分成多個(gè)任務(wù),并且所有任務(wù)都獨(dú)立運(yùn)行。當(dāng)我們處理大型數(shù)據(jù)集時(shí),即使apply函數(shù)看起來(lái)也很慢。

因此,讓我們看看如何利用Python中的多進(jìn)程庫(kù)加快處理速度。

我們將隨機(jī)創(chuàng)建一百萬(wàn)個(gè)值,并求出每個(gè)值的除數(shù)。我們將使用apply函數(shù)和多進(jìn)程方法比較其性能:

# 導(dǎo)入庫(kù)
import pandas as pd
import math
import multiprocessing as mp
from random import randint
# 計(jì)算除數(shù)的函數(shù)
def countDivisors(n) : 
 count = 0
 for i in range(1, (int)(math.sqrt(n)) + 1) : 
 if (n % i == 0) : 
 if (n / i == i) : 
 count = count + 1
 else : 
 count = count + 2
 return count 
# 創(chuàng)建隨機(jī)數(shù) 
random_data = [randint(10,1000) for i in range(1,1000001)]
data = pd.DataFrame({'Number' : random_data })
data.shape
優(yōu)化Python代碼的4種方法

 

%%time
data['Number_of_divisor'] = data.Number.apply(countDivisors)
優(yōu)化Python代碼的4種方法

 

%%time
pool = mp.Pool(processes = (mp.cpu_count() - 1))
answer = pool.map(countDivisors,random_data)
pool.close()
pool.join()
優(yōu)化Python代碼的4種方法

 

在這里,多進(jìn)程比apply方法快13倍。性能可能會(huì)因不同的硬件系統(tǒng)而異,但肯定會(huì)提高性能。

結(jié)束

這絕不是詳盡的列表。還有許多其他方法和技術(shù)可以優(yōu)化Python代碼。但是我在數(shù)據(jù)科學(xué)生涯中發(fā)現(xiàn)并使用了很多這四個(gè),相信你也會(huì)發(fā)現(xiàn)它們也很有用。

英文原文網(wǎng)址

https://www.analyticsvidhya.com/blog/2019/09/4-methods-optimize-python-code-data-science/

在原文上可以在線執(zhí)行代碼

分享到:
標(biāo)簽:優(yōu)化 Python
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定