Pandas字符串操作的各種方法及速度測(cè)試
引言
由于LLM的發(fā)展, 很多的數(shù)據(jù)集都是以DF的形式發(fā)布的,所以通過(guò)Pandas操作字符串的要求變得越來(lái)越高了,所以本文將對(duì)字符串操作方法進(jìn)行基準(zhǔn)測(cè)試,看看它們是如何影響pandas的性能的。因?yàn)橐坏㏄andas在處理數(shù)據(jù)時(shí)超過(guò)一定限制,它們的行為就會(huì)很奇怪。
我們用Faker創(chuàng)建了一個(gè)100,000行的測(cè)試數(shù)據(jù)。
測(cè)試方法
安裝:
!pip install faker
生成測(cè)試數(shù)據(jù)的方法很簡(jiǎn)答:
import pandas as pd import numpy as np def gen_data(x): from faker import Faker fake = Faker() outdata = {} for i in range(0,x): outdata[i] = fake.profile() return pd.DataFrame(outdata).T n= 100000 basedata = gen_data(n)
然后把Google Colab將輸出存儲(chǔ)在Google drive中
from google.colab import drive drive.mount('/content/drive')
創(chuàng)建了非常簡(jiǎn)單的函數(shù)來(lái)測(cè)試連接兩個(gè)字符串的各種方法。
def process(a,b): return ''.join([a,b]) def process(a,b): return a+b def process(a,b): return f"{a}" def process(a,b): return f"{a}"*100
創(chuàng)建一個(gè)空DF,編寫(xiě)一個(gè)函數(shù)將輸出%%timeit作為一行添加到數(shù)據(jù)框中
# add a row to the dataframe using %%timeit output def add_to_df(n, m, x, outputdf): outputdf.loc[len(outputdf.index)] = [m, n, x] # output frame outputdf = pd.DataFrame(columns=['method', 'n', 'timing']) outputdf
然后就是運(yùn)行上面的每個(gè)函數(shù)并將數(shù)據(jù)導(dǎo)出到pandas的代碼。
# get a sample of data n = 10000 suffix = 'fstring_100x' data = basedata.copy().sample(n).reset_index()
記錄運(yùn)行時(shí)間
%%timeit -r 7 -n 1 -o data['newcol'] = '' for row in range(len(data)): data.at[row ,'newcol'] = process(data.at[row, 'job'], data.at[row, 'company']) # 451 ms ± 34 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # <TimeitResult : 451 ms ± 34 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)>
完整的函數(shù)調(diào)用
m = "Iterating over the rows" add_to_df(n = n, m = m, x = vars(_), outputdf = outputdf)
試驗(yàn)
上面是代碼,下面開(kāi)始用上面的代碼進(jìn)行試驗(yàn):
Iterrows (pandas原生函數(shù))每行相加
%%timeit -r 7 -n 1 -o data['newcol'] = '' for row, item in data.iterrows(): data.at[row ,'newcol'] = process(item['job'], item['company'])
Itertuples(由于不可變而更安全)每行相加
%%timeit -r 7 -n 1 -o data['newcol'] = '' for row, job, company in data[['job','company']].itertuples(): data.at[row ,'newcol'] = process(job, company)
使用pandas原生函數(shù)作為字符串相加
%%timeit -r 7 -n 1 -o data['newcol'] = data.job + data.company
使用原生函數(shù)pandas. series .add
%%timeit -r 7 -n 1 -o data['newcol'] = data.job.add(data.company)
使用dataframe.apply
%%timeit -r 7 -n 1 -o data['newcol'] = data.apply(lambda row: process(row['job'],row['company']), axis=1)
使用List Map
%%timeit -r 7 -n 1 -o data['newcol'] = list(map(process, data.job, data.company))
Pandas矢量化
%%timeit -r 7 -n 1 -o data['newcol'] = process(data.job, data.company)
numpy數(shù)組矢量化
%%timeit -r 7 -n 1 -o data['newcol'] = process(data.job.to_numpy(), data.company.to_numpy())
顯式在numpy數(shù)組上使用numpy向量化
%%timeit -r 7 -n 1 -o data['newcol'] = np.vectorize(process)(data.job.to_numpy(), data.company.to_numpy())
優(yōu)化后的列表推導(dǎo)式
%%timeit -r 7 -n 1 -o data['newcol'] = '' data['newcol'] =[process(i,j) for i,j in list(zip(data.job, data.company)) ]
最后是結(jié)果的輸出:
outputdf.to_csv(f"./drive/MyDrive/{n}_{suffix}.csv")
結(jié)果
結(jié)果如下所示。我用了上面3種不同函數(shù)測(cè)試了結(jié)果。
原生的字符串加法C = a+b
從1000行擴(kuò)展到100,000行所需的時(shí)間;
可視化對(duì)比:
所有矢量化方法都非???,而且pandas標(biāo)準(zhǔn)的str.add對(duì)numpy數(shù)組也進(jìn)行了矢量化。能夠看到Pandas的原生方法一般都是線性的。List-map似乎以N的平方根的速度增長(zhǎng)
使用fstring: c = f " {a} "
使用fstring,結(jié)果很有趣,有的結(jié)果無(wú)法解釋。
時(shí)間
可視化
從時(shí)間上看,長(zhǎng)度超過(guò)10,000的DF時(shí),向量化是正確執(zhí)行的
下圖是第三個(gè)函數(shù),就是*100,這更能說(shuō)明問(wèn)題,向量化操作的基本上時(shí)間沒(méi)有變化
總結(jié)
通過(guò)上面的測(cè)試,我們可以總結(jié)一下結(jié)果:
1、還是老生常談的問(wèn)題,不要使用iterrows(), itertuples(),盡量不要使用DataFrame.apply(),因?yàn)閹讉€(gè)函數(shù)還是循環(huán)遍歷的。
2、矢量化操作在字符串操作中也是可以使用的,但是為了安全起見(jiàn),使用Numpy數(shù)組。
3、列表推導(dǎo)式就像它的名字一樣,它還是一個(gè)list
4、還有一些奇怪的無(wú)法解釋的問(wèn)題,但是大部分的情況都是可以解釋的
以上就是Pandas字符串操作的各種方法及速度測(cè)試的詳細(xì)內(nèi)容,更多關(guān)于Pandas字符串操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中報(bào)錯(cuò) “TypeError: ‘list‘ object is&n
這篇文章主要介紹了Python中報(bào)錯(cuò) “TypeError: ‘list‘ object is not callable”問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09python實(shí)現(xiàn)摳圖給證件照換背景源碼
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)摳圖給證件照換背景源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08python爬蟲(chóng)獲取百度首頁(yè)內(nèi)容教學(xué)
在本篇內(nèi)容里小編給大家分享了關(guān)于python爬蟲(chóng)獲取百度首頁(yè)內(nèi)容教學(xué),需要的朋友們可以跟著學(xué)習(xí)下。2018-12-12Python人工智能之混合高斯模型運(yùn)動(dòng)目標(biāo)檢測(cè)詳解分析
運(yùn)動(dòng)目標(biāo)檢測(cè)是計(jì)算機(jī)視覺(jué)領(lǐng)域中的一個(gè)重要內(nèi)容,其檢測(cè)效果將會(huì)對(duì)目標(biāo)跟蹤與識(shí)別造成一定的影響,本文將介紹用Python來(lái)進(jìn)行混合高斯模型運(yùn)動(dòng)目標(biāo)檢測(cè),感興趣的朋友快來(lái)看看吧2021-11-11python3?http.client?網(wǎng)絡(luò)請(qǐng)求方式
這篇文章主要介紹了python3?http.client?網(wǎng)絡(luò)請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Python實(shí)現(xiàn)提取XML內(nèi)容并保存到Excel中的方法
這篇文章主要介紹了Python實(shí)現(xiàn)提取XML內(nèi)容并保存到Excel中的方法,涉及Python針對(duì)xml文件的讀取、解析以及Excel文件的寫(xiě)入、保存等相關(guān)操作技巧,需要的朋友可以參考下2018-09-09python實(shí)現(xiàn)一次創(chuàng)建多級(jí)目錄的方法
這篇文章主要介紹了python實(shí)現(xiàn)一次創(chuàng)建多級(jí)目錄的方法,涉及Python中os模塊makedirs方法的使用技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05