Python遍歷pandas數(shù)據(jù)方法總結(jié)
前言
Pandas是python的一個(gè)數(shù)據(jù)分析包,提供了大量的快速便捷處理數(shù)據(jù)的函數(shù)和方法。其中Pandas定義了Series 和 DataFrame兩種數(shù)據(jù)類型,這使數(shù)據(jù)操作變得更簡(jiǎn)單。Series 是一種一維的數(shù)據(jù)結(jié)構(gòu),類似于將列表數(shù)據(jù)值與索引值相結(jié)合。DataFrame 是一種二維的數(shù)據(jù)結(jié)構(gòu),接近于電子表格或者mysql數(shù)據(jù)庫(kù)的形式。

在數(shù)據(jù)分析中不可避免的涉及到對(duì)數(shù)據(jù)的遍歷查詢和處理,比如我們需要將dataframe兩列數(shù)據(jù)兩兩相除,并將結(jié)果存儲(chǔ)于一個(gè)新的列表中。本文通過(guò)該例程介紹對(duì)pandas數(shù)據(jù)遍歷的幾種方法。
for..in循環(huán)迭代方式
for語(yǔ)句是Python內(nèi)置的迭代器工具,用于從可迭代容器對(duì)象(如列表、元組、字典、集合、文件等)中逐個(gè)讀取元素,直到容器中沒(méi)有更多元素為止,工具和對(duì)象之間只要遵循可迭代協(xié)議即可進(jìn)行迭代操作。
具體的迭代的過(guò)程:可迭代對(duì)象通過(guò)__iter__方法返回迭代器,迭代器具有__next__方法,for循環(huán)不斷地調(diào)用__next__方法,每次按序返回迭代器中的一個(gè)值,直到迭代到最后,沒(méi)有更多元素時(shí)拋出異常StopIteration(python自動(dòng)處理異常)。迭代的優(yōu)點(diǎn)是無(wú)需把所有元素一次加載到內(nèi)存中,可以在調(diào)用next方法時(shí)逐個(gè)返回元素,避免出現(xiàn)內(nèi)存空間不夠的情況。
>>> x = [1,2,3] >>> its = x.__iter__() #列表是可迭代對(duì)象,否則會(huì)提示不是迭代對(duì)象 >>> its <list_iterator object at 0x100f32198> >>> next(its) # its包含此方法,說(shuō)明its是迭代器 1 >>> next(its) 2 >>>next(its) 3 >>> next(its) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration

實(shí)現(xiàn)代碼如下:
def haversine_looping(df): disftance_list = [] for i in range(0,len(df)): disftance_list.append(df.iloc[i][‘high']/df.iloc[i][‘open']) return disftance_list
關(guān)于上述代碼中range的實(shí)現(xiàn)方法,我們也可根據(jù)迭代器協(xié)議自實(shí)現(xiàn)相同功能的迭代器(自帶iter方法和next方法)應(yīng)用在for循環(huán)中,代碼如下:
class MyRange: def __init__(self, num): self.i = 0 self.num = num def __iter__(self): return self def __next__(self): if self.i < self.num: i = self.i self.i += 1 return i else: raise StopIteration() for i in MyRange(10): print(i)
我們也可以通過(guò)列表解析的方式用更少的代碼實(shí)現(xiàn)數(shù)據(jù)處理功能
disftance_list = [df.iloc[i][‘high']/df.iloc[i][‘open'] for i in range(0,len(df))]
iterrows()生成器方式
iterrows是對(duì)dataframe行進(jìn)行迭代的一個(gè)生成器,它返回每行的索引及包含行本身的對(duì)象。所謂生成器其實(shí)是一種特殊的迭代器,內(nèi)部支持了迭代器協(xié)議。Python中提供生成器函數(shù)和生成器表達(dá)式兩種方式實(shí)現(xiàn)生成器,每次請(qǐng)求返回一個(gè)結(jié)果,不需要一次性構(gòu)建一個(gè)結(jié)果列表,節(jié)省了內(nèi)存空間。
生成器函數(shù):編寫(xiě)為常規(guī)的def語(yǔ)句,但是使用yield語(yǔ)句一次返回一個(gè)結(jié)果,在每個(gè)結(jié)果之間掛起和繼續(xù)它們的狀態(tài)。
def gensquares(N): for i in range(N): yield i**2 print gensquares(5) for i in gensquares(5): print(i) <generator object gensquares at 0xb3d37fa4> 0 1 4 9 16
生成器表達(dá)式:類似列表解析,按需產(chǎn)生結(jié)果的一個(gè)對(duì)象。
print (x**2 for x in range(5)) print list(x**2 for x in range(5)) <generator object <genexpr> at 0xb3d31fa4> [0, 1, 4, 9, 16]
iterrows()實(shí)現(xiàn)代碼如下:
def haversine_looping(df): disftance_list = [] for index,row in df.iterrows(): disftance_list.append(row[‘high']/row[‘open']) return disftance_list
iterrows代碼如下,yield語(yǔ)句掛起該函數(shù)并向調(diào)用者發(fā)送回一組值:
def iterrows(self): columns = self.columns klass = self._constructor_sliced for k, v in zip(self.index, self.values): s = klass(v, index=columns, name=k) yield k, s
apply()方法循環(huán)方式
apply()方法可將函數(shù)應(yīng)用于dataframe特定行或列。函數(shù)由lambda方式在代碼中內(nèi)嵌實(shí)現(xiàn),lambda函數(shù)的末尾包含axis參數(shù),用來(lái)告知Pandas將函數(shù)運(yùn)用于行(axis = 1)或者列(axis = 0)。
實(shí)現(xiàn)代碼如下:
df.apply(lambda row: row[‘high']/row[‘open'], axis =1)
Pandas series 的矢量化方式
Pandas的DataFrame、series基礎(chǔ)單元數(shù)據(jù)結(jié)構(gòu)基于鏈表,因此可將函數(shù)在整個(gè)鏈表上進(jìn)行矢量化操作,而不用按順序執(zhí)行每個(gè)值。Pandas包括了非常豐富的矢量化函數(shù)庫(kù),我們可把整個(gè)series(列)作為參數(shù)傳遞,對(duì)整個(gè)鏈表進(jìn)行計(jì)算。
實(shí)現(xiàn)代碼如下:
dftest4['rate'] = dftest4['high']/dftest4['open']
Numpy arrays的矢量化方式
由于函數(shù)的矢量化實(shí)現(xiàn)中只使用了series的數(shù)值,因此可使用values 方法將鏈表從Pandas series轉(zhuǎn)換為NumPy arrays,把NumPy array作為參數(shù)傳遞,對(duì)整個(gè)鏈表進(jìn)行計(jì)算。
實(shí)現(xiàn)代碼如下:
dftest5['rate'] = dftest5['high'].values/dftest5['open'].values
總結(jié)
使用timeit方法對(duì)以上幾種遍歷方式進(jìn)行執(zhí)行時(shí)間測(cè)試,測(cè)試結(jié)果如下??梢钥闯鲅h(huán)執(zhí)行的速度是最慢的,iterrows()針對(duì)Pandas的dataframe進(jìn)行了優(yōu)化,相比直接循環(huán)有顯著提升。apply()方法也是在行之間進(jìn)行循環(huán),但由于利用了類似Cython的迭代器的一系列全局優(yōu)化,其效率要比iterrows高很多。NumPy arrays的矢量化運(yùn)行速度最快,其次是Pandas series矢量化。由于矢量化是同時(shí)作用于整個(gè)序列的,可以節(jié)省更多的時(shí)間,相比使用標(biāo)量操作更好,NumPy使用預(yù)編譯的C代碼在底層進(jìn)行優(yōu)化,同時(shí)也避免了Pandas series操作過(guò)程中的很多開(kāi)銷,例如索引、數(shù)據(jù)類型等等,因此,NumPy arrays的操作要比Pandas series快得多。
相關(guān)文章
Python如何通過(guò)subprocess調(diào)用adb命令詳解
python可以說(shuō)是寫(xiě)一些小腳本的利器語(yǔ)法簡(jiǎn)單,做為最著名的就“膠水語(yǔ)言”用它來(lái)寫(xiě)一些命令腳本非常的方便。下面這篇文章主要給大家介紹了關(guān)于Python如何通過(guò)subprocess調(diào)用adb命令的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08
150行python代碼實(shí)現(xiàn)貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了150行python代碼實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
python中使用pyhook實(shí)現(xiàn)鍵盤監(jiān)控的例子
這篇文章主要介紹了python中使用pyhook實(shí)現(xiàn)鍵盤監(jiān)控的例子,包含pyhook的下載地址和手冊(cè)地址及一個(gè)Windows下的監(jiān)控實(shí)例,需要的朋友可以參考下2014-07-07
安裝pycurl報(bào)錯(cuò)Could not run curl-config: &ap
這篇文章主要為大家介紹了安裝pycurl報(bào)錯(cuò)Could not run curl-config: 'curl-config'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
python?ConfigParser庫(kù)的使用及遇到的坑
這篇文章主要介紹了python?ConfigParser庫(kù)的使用及遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Python安裝Gradio和常見(jiàn)安裝問(wèn)題解決辦法
Gradio是一款便捷的Python庫(kù),專門用于創(chuàng)建機(jī)器學(xué)習(xí)模型的Web應(yīng)用,安裝通常簡(jiǎn)單,但偶爾會(huì)遇到依賴問(wèn)題或環(huán)境配置錯(cuò)誤,這篇文章主要介紹了Python安裝Gradio和常見(jiàn)安裝問(wèn)題解決辦法,需要的朋友可以參考下2024-10-10
Python機(jī)器學(xué)習(xí)NLP自然語(yǔ)言處理基本操作精確分詞
本文是Python機(jī)器學(xué)習(xí)NLP自然語(yǔ)言處理系列文章,帶大家開(kāi)啟一段學(xué)習(xí)自然語(yǔ)言處理 (NLP) 的旅程. 本文主要學(xué)習(xí)NLP自然語(yǔ)言處理基本操作之如何精確分詞2021-09-09

