一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

如何用 Pandas 存取和交換數(shù)據(jù)?

 LibraryPKU 2019-05-31

王樹義

讀完需要

22
分鐘

速讀僅需8分鐘

本文為你介紹 Pandas 存取數(shù)據(jù)的3種主要格式,以及使用中的注意事項(xiàng)。

問題

在數(shù)據(jù)分析的過程里,你已經(jīng)體會到 Python 生態(tài)系統(tǒng)的強(qiáng)大了吧?

數(shù)據(jù)采集、整理、可視化、統(tǒng)計(jì)分析……一直到深度學(xué)習(xí),都有相應(yīng)的 Python 包支持。

但是你會發(fā)現(xiàn),沒有任何一個(gè) Python 軟件包,是全能的。

這是一種非常好的設(shè)計(jì)思維——用優(yōu)秀的工具,做專業(yè)的事兒;用許多優(yōu)秀工具組成的系統(tǒng),來有條不紊地處理復(fù)雜問題。

所以,在這個(gè)過程中,你大概率會經(jīng)常遇到數(shù)據(jù)的交換問題。

有時(shí)候,是把分析結(jié)果存起來,下次讀取回來繼續(xù)使用。

更重要的時(shí)候,是把一個(gè)工具的分析結(jié)果導(dǎo)出,導(dǎo)入到另一個(gè)工具包中。

這些數(shù)據(jù)存取的功能,幾乎分布在每一個(gè) Python 數(shù)據(jù)科學(xué)軟件包之內(nèi)。

但是,其中有一個(gè)最重要的樞紐,那就是 Pandas 。

我不止一次跟你提起過,學(xué)好 Pandas 的重要性

很多情況下,看似復(fù)雜的數(shù)據(jù)整理與可視化,Pandas 只需要一行語句就能搞定。

回顧我們的教程里,也曾使用過各種不同的格式讀取數(shù)據(jù)到 Pandas 進(jìn)行處理。

然而,當(dāng)你需要自己獨(dú)立面對軟件包的格式要求時(shí),也許僅僅是因?yàn)椴涣私馊绾握_生成或讀取某種格式,結(jié)果導(dǎo)致出錯(cuò),甚至?xí)鼓銌适剿鞯男判呐c興趣。

這篇教程里,我以咱們介紹過多次的情感分類數(shù)據(jù)作為例子,用最小化的數(shù)據(jù)集,詳細(xì)為你介紹若干種常見的存取數(shù)據(jù)格式。

有了這些知識與技能儲備,你就可以應(yīng)對大多數(shù)同類數(shù)據(jù)分析問題的場景了。

環(huán)境

為了方便你完整重現(xiàn)我教程中的代碼,我使用 Google Colab 撰寫和運(yùn)行,并且存儲副本到了 Github 里面。

請?jiān)谖业墓娞枴坝駱渲ヌm”(nkwangshuyi)后臺輸入“export”,就可以獲得本教程相應(yīng)的 Github 鏈接,以及代碼運(yùn)行環(huán)境的使用說明了。

數(shù)據(jù)

為了盡量簡化問題,我們這里手動輸入兩條文本,構(gòu)建一個(gè)超小型的評論情感數(shù)據(jù)集。

str1 = '這是個(gè)好電影,\n我喜歡!'
str2 = '這部劇的\t第八季\t糟透了!'

(猜猜看,其中 str2 里面的“這部劇”是哪一部?)

你看到了,這里我加了一些特殊符號進(jìn)去。

其中:

  • \n :換行符。有時(shí)候原始評論是分段的,所以出現(xiàn)它很正常;

  • \t :制表符。對應(yīng)鍵盤上的 Tab 鍵,一般在代碼里用于縮進(jìn)。用在評論句子中其實(shí)很奇怪。這里只是舉個(gè)例子,下文你會看到它的特殊性。

我們打印一下兩個(gè)字符串,看是否正確輸入:

print(str1)
這是個(gè)好電影,
我喜歡!

換行符正確顯示了。下面我們看看制表符。

print(str2)
這部劇的 第八季 糟透了!

好了,下面我們分別賦予兩句話情感標(biāo)記,然后用 Pandas 構(gòu)建數(shù)據(jù)框。

import pandas as pd

我們建立了一個(gè)字典(dict),分別將文本和標(biāo)記列表放到 textlabel 下面。然后,用 Pandas 的默認(rèn)構(gòu)建方式,自動將其轉(zhuǎn)化為數(shù)據(jù)框(Dataframe)。

df = pd.DataFrame({'text': [str1, str2], 'label': [1, 0]})
df

顯示效果如下:

好了,數(shù)據(jù)已經(jīng)正確存儲到 Pandas 里面了。下面我們分別看看幾種輸出格式如何導(dǎo)出,以及它們的特點(diǎn)和常見問題。

CSV/TSV

我們來看最常見的兩種格式,分別是:

  • csv :逗號分隔數(shù)據(jù)文本文件;

  • tsv :制表符分隔數(shù)據(jù)文本文件;

先嘗試把 Pandas 數(shù)據(jù)框?qū)С鰹?csv 文件。

df.to_csv('data.csv', index=None)

注意這里我們使用了一個(gè) index=None 參數(shù)。

回顧剛才的輸出:

上圖中標(biāo)紅色的地方,就是索引(index)。如果我們不加入 index=None 參數(shù)說明,那么這些數(shù)值型索引也會一起寫到 csv 文件里面去。對我們來說,這沒有必要,會白白占用存儲空間。

將生成的 csv 文件拖入文本編輯器內(nèi),效果如下:

你可以清楚地看到,逗號分割了表頭和數(shù)據(jù)。

有意思的是,因?yàn)榈谝痪湓u論里包含了換行符,所以就真的記錄到兩行上面。而文本的兩端,有引號包裹。

第二句話,制表符(縮進(jìn))也是正確顯示了。但是這句話兩端,卻沒有引號。

這么亂七八糟的結(jié)果,Pandas 還能夠正確讀回來嗎?

我們試試看。

pd.read_csv('data.csv')

一切正常。

看來,在讀取 csv 的過程里,Pandas 還是很有適應(yīng)能力的。

下面我們來看看頗為類似的 tsv 格式。

Pandas 并不提供一個(gè)單獨(dú)的 to_tsv 選項(xiàng)。我們依然需要利用 to_csv 方法。

只不過,這次我們添加一個(gè)參數(shù)  sep='\t' 。

df.to_csv('data.tsv', index=None, sep='\t')

生成的文件名為 data.tsv 。我們還是在編輯器里面打開它看看。

對比一下剛剛的 csv 格式,你發(fā)現(xiàn)了什么?

大體上二者差不多。

只是逗號都變成了制表符縮進(jìn)而已。

但是不知你是否發(fā)現(xiàn),第二句話此時(shí)也被引號包裹起來了。

為什么呢?

對,因?yàn)檫@句話里面含有制表符。如果不包裹,讀取的時(shí)候可就要出問題了。程序就會傻乎乎地把 “第八季” 當(dāng)成標(biāo)記,扔掉后面的內(nèi)容了。

你看現(xiàn)在編輯器的著色,實(shí)際上已經(jīng)錯(cuò)誤判斷分列了。

我們試著用 Pandas 把它讀取回來。

注意,這里我們依然指定了,分割符是 sep='\t' 。

pd.read_csv('data.tsv', sep='\t')

沒有差別,效果依然很好。

這兩種數(shù)據(jù)導(dǎo)出格式,非常直觀簡潔,用文本編輯器就可以打開查看。而且導(dǎo)出讀取都很方便。

這是不是意味著,我們只要會用這兩種格式就可以了呢?

別忙,我們再來看一個(gè)使用案例。

在處理中文文本信息時(shí),我們經(jīng)常需要做的一件事情,就是分詞。

這里,我們把之前兩句話進(jìn)行分詞后,再嘗試保存和讀取。

為了分詞,我們先安裝一個(gè)jieba分詞包。

!pip install jieba

然后把它讀取進(jìn)來。

import jieba

前面我們給自己挖了個(gè)坑——為了說明特殊符號的存儲,我們加了換行符和制表符?,F(xiàn)在問題來了,分詞之后,我們肯定不想要這些符號。

怎么辦呢?

我們來編寫一個(gè)定制化的分詞函數(shù)就好了。

這個(gè)函數(shù)里,我們分別清除掉制表符和換行符,然后再用結(jié)巴分詞切割。分詞這里,我們用的是默認(rèn)參數(shù)

因?yàn)榉衷~后的結(jié)果實(shí)際上是個(gè)生成器(generator),而我們是需要真正的列表(list)的,所以利用 list 函數(shù)強(qiáng)制轉(zhuǎn)換分詞結(jié)果成為列表。

def cleancut(s):
s = s.replace('\t', '')
s = s.replace('\n', '')
return list(jieba.cut(s))

我們生成一個(gè)新的數(shù)據(jù)框 df_list ,克隆原先的 df 。

df_list = df.copy()

然后,我們把分詞的結(jié)果,存到新的數(shù)據(jù)框 df_listtext 列上面。

df_list.text = df.text.apply(cleancut)

看看分詞后的效果:

df_list

怎么證明 text 上存儲的確實(shí)是個(gè)列表呢?

我們來讀取一下其中的第一個(gè)元素好了。

df_list.text.iloc[0][0]

結(jié)果顯示為:

'這'

很好。此時(shí)的數(shù)據(jù)框可以正確存儲預(yù)處理(分詞)的結(jié)果。

下面我們還是仿照原先的方式,把這個(gè)處理結(jié)果數(shù)據(jù)導(dǎo)出,然后再導(dǎo)入。

先嘗試 csv 格式。

df_list.to_csv('data_list.csv', index=None)

導(dǎo)出過程一切正常。

我們來看看生成的 csv 文件。

在存儲的過程中,列表內(nèi)部,每個(gè)元素都用單引號包裹。整體列表的外部,被雙引號包裹。

至于分割符嘛,依然是逗號

看著是不是很正常?

我們來嘗試把它讀取回來。當(dāng)然我們希望讀取回來的格式,跟當(dāng)時(shí)導(dǎo)出的一模一樣。

pd.read_csv('data_list.csv')

結(jié)果是這樣的:

初看起來,很好??!

但是,我們把它和導(dǎo)出之前的數(shù)據(jù)框?qū)Ρ纫幌拢銇硗鎯阂粋€(gè)“大家來找茬”游戲吧。

注意,導(dǎo)出之前,列表當(dāng)中的每一個(gè)元素,都沒有引號包裹的。

但是重新讀取回來的內(nèi)容,每一個(gè)元素多了個(gè)單引號。

這看起來,似乎也不是什么大毛病啊。

然而,我們需要驗(yàn)證一下:

pd.read_csv('data_list.csv').text.iloc[0][0]

這次程序給我們返回的第一行文本分割的第一個(gè)元素,是這樣的:

'['

不應(yīng)該是“這”嗎?

我們來看看下一個(gè)元素是“這”嗎?

pd.read_csv('data_list.csv').text.iloc[0][1]

答案是:

'''

看到這里,你可能已經(jīng)恍然大悟。原來導(dǎo)出 csv 的時(shí)候,原先的分詞列表被當(dāng)成了字符串;導(dǎo)入進(jìn)來的時(shí)候,干脆就是個(gè)字符串了。

可是我們需要的是個(gè)列表啊,這個(gè)字符串怎么用?

來看看 tsv 格式是不是對我們的問題有幫助。

df_list.to_csv('data_list.tsv', index=None, sep='\t')

打開導(dǎo)出的 tsv 文件。

列表就是列表,兩邊并沒有用雙引號包裹。

這次興許能成!

我們趕緊讀回來看看。

pd.read_csv('data_list.tsv', sep='\t')

這結(jié)果,立刻讓人心里涼了一半。

因?yàn)榱斜砝锩婷總€(gè)元素兩旁的單引號都在啊。

抱著一絲僥幸的心理,我們嘗試一下驗(yàn)證第一個(gè)元素。

pd.read_csv('data_list.tsv', sep='\t').text.iloc[0][0]

果不其然,還是中括號

這意味著讀回來的,還是一個(gè)字符串。

任務(wù)失敗。

看來,依靠 csv/tsv 格式把列表導(dǎo)出導(dǎo)入,是不合適的。

那我們該怎么辦呢?

pickle

好消息是,我們可以用 pickle 。

pickle 是一種二進(jìn)制格式,在 Python 生態(tài)系統(tǒng)中,擁有廣泛的支持。

例如 PyTorch 的預(yù)訓(xùn)練模型,就可以用它來存儲和讀取。

在 Pandas 里面使用 pickle,非常簡單,和 csv 一樣有專門的命令,而且連參數(shù)都可以不用修改添加。

df_list.to_pickle('data.pickle')

讀取回來,也很方便。

df_list_loaded = pd.read_pickle('data.pickle')

我們來看看讀取回來的數(shù)據(jù)是否正確:

df_list_loaded

這次看著好多了,那些讓我們煩惱的引號都不見了。

驗(yàn)證一下第一行列表的第一個(gè)元素:

df_list_loaded.text.iloc[0][0]

結(jié)果是:

'這'

很讓人欣喜的結(jié)果??!

看來 pickle 格式果然靠譜。

不過,當(dāng)我們試圖在文本編輯器里打開 pickle 格式的時(shí)候,會有警告。

如果我們忽略警告,一意孤行。那么確實(shí)還是可以打開的。

只不過,你看得懂嗎?

反正我是看不懂的。

這就是二進(jìn)制存儲方式的問題——只適合機(jī)器來看,人讀起來如同天書。

但這其實(shí)還不是 pickle 格式最大的問題。

最大的問題,在于不同軟件包之間的交互。

我們在做數(shù)據(jù)分析的時(shí)候,難免會調(diào)用 Pandas 以外的軟件包,繼續(xù)分析我們用 Pandas 預(yù)處理后的文件。

這個(gè)時(shí)候,就要看對方支持的文件格式有哪些了。

一個(gè)最常見的例子,是 PyTorch 的文本工具包 torchtext 。

用它讀取數(shù)據(jù)的時(shí)候,格式列表里面不包含 pickle 。

這可糟糕了。我們前面需要 Pandas 來預(yù)處理分詞,后面又需要使用 Torchtext 來劃分訓(xùn)練集和驗(yàn)證集,生成迭代(iteration)數(shù)據(jù)流,以便輸入模型做訓(xùn)練。

可在二者中間,我們卻被交換格式問題卡住了。

好在,天無絕人之路。

你看,這里列出的格式列表,除了 csv 和 tsv (已被我們驗(yàn)證過不適合處理分詞列表)之外,還有一個(gè) JSON 。

JSON

JSON 絕對是數(shù)據(jù)交換界的一等公民。

它不僅可以存儲結(jié)構(gòu)化數(shù)據(jù)(也就是我們例子里面的數(shù)據(jù)框,或者你更常見的 Excel 表格),也可以存儲非結(jié)構(gòu)化數(shù)據(jù)。

如果你跟著我的教程了解過一些 API 的 Python 調(diào)用方法,那你對 JSON 格式應(yīng)該并不陌生。

本例中我們使用的,是一種特殊的 JSON 格式,叫做 JSON Lines。

之所以用它,是因?yàn)榍懊嫖覀兘榻B的 torchtext 包,要求使用這種格式。

所以,在 Pandas 的 to_json 函數(shù)里,我們還要專門加上兩個(gè)參數(shù):

  • orient='records' :每一行數(shù)據(jù)單獨(dú)作為字典形式輸出;

  • lines=True :去掉首尾的外部括號,并且每一行數(shù)據(jù)之間不加逗號。

df_list.to_json('data.json', orient='records', lines=True)

輸出的結(jié)果,是這個(gè)樣子的。

由于中文采用了 unicode 方式存儲,所以此處我們無法直接識別每一個(gè)漢字。

但是,存儲的格式,以及其他類型的數(shù)據(jù)記錄,還是能看得一清二楚的。

我們來嘗試讀入。方法與輸出類似,也是用同樣的參數(shù)。

df_list_loaded_json = pd.read_json('data.json', orient='records', lines=True)

看看讀入效果:

df_list_loaded_json

首先,你會發(fā)現(xiàn)列的位置發(fā)生了調(diào)換。好在對于數(shù)據(jù)框來說,這不是問題,因?yàn)榱兄g的相對位置本來也沒有特殊含義。

其次,你能看到,那些引號都沒有出現(xiàn)。

為了進(jìn)一步驗(yàn)證,我們還是調(diào)取第一行列表的第一個(gè)元素。

df_list_loaded_json.text.iloc[0][0]

顯示為:

'這'

太棒了!

這樣一來, Pandas 就可以和 torchtext 等軟件包之間,建立順暢而牢固的數(shù)據(jù)交換通道了。

小結(jié)

通過閱讀本文,希望你已經(jīng)掌握了以下知識點(diǎn):

  • Pandas 數(shù)據(jù)框常用的數(shù)據(jù)導(dǎo)出格式;

  • csv/tsv 對于文本列表導(dǎo)出和讀取中會遇到的問題;

  • pickle 格式的導(dǎo)出與導(dǎo)入,以及二進(jìn)制文件難以直接閱讀的問題;

  • JSON Lines 格式的輸入輸出方法及其應(yīng)用場景;

  • 如何自定義函數(shù),在分詞的時(shí)候去掉特殊符號。

希望這些知識和技能,可以幫助你解決研究和工作中遇到的實(shí)際問題。

深度學(xué)習(xí)愉快!

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    黄色片一区二区三区高清| 91天堂素人精品系列全集| 久久精品国产亚洲av久按摩| 久久精品免费视看国产成人| 少妇高潮呻吟浪语91| 午夜视频免费观看成人| 午夜国产精品国自产拍av| 草草草草在线观看视频| 日本高清不卡一二三区| 婷婷一区二区三区四区| 成人你懂的在线免费视频| 99久久精品久久免费| 欧美又黑又粗大又硬又爽| 亚洲欧美日韩熟女第一页| 欧美国产日韩变态另类在线看| 一二区中文字幕在线观看| 欧美日韩在线观看自拍| 中文字幕一区二区久久综合| 日韩中文字幕欧美亚洲| 亚洲成人免费天堂诱惑| 日本特黄特色大片免费观看| 久久老熟女一区二区三区福利| 久久精品国产一区久久久| 日本二区三区在线播放| 欧美一区二区三区在线播放| 国产精品一区二区三区日韩av| 午夜精品在线视频一区| 国产精品成人免费精品自在线观看| 中文字幕无线码一区欧美| 日韩一级欧美一级久久| 国产老女人性生活视频| 在线欧美精品二区三区| 欧美一区二区三区五月婷婷| 成年人黄片大全在线观看| 日本99精品在线观看| 色婷婷在线视频免费播放| 午夜成年人黄片免费观看| 亚洲精品成人午夜久久| 欧美日韩国产的另类视频| 欧美色婷婷综合狠狠爱| 欧美日不卡无在线一区|