乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       LibraryPKU 2019-05-31

      王樹義

      讀完需要

      22
      分鐘

      速讀僅需8分鐘

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

      問題

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

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

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

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

      所以,在這個(gè)過程中,你大概率會(huì)經(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ú)立面對(duì)軟件包的格式要求時(shí),也許僅僅是因?yàn)椴涣私馊绾握_生成或讀取某種格式,結(jié)果導(dǎo)致出錯(cuò),甚至?xí)鼓銌适剿鞯男判呐c興趣。

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

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

      環(huán)境

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

      請(qǐng)?jiān)谖业墓娞?hào)“玉樹芝蘭”(nkwangshuyi)后臺(tái)輸入“export”,就可以獲得本教程相應(yīng)的 Github 鏈接,以及代碼運(yùn)行環(huán)境的使用說明了。

      數(shù)據(jù)

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

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

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

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

      其中:

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

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

      我們打印一下兩個(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)建方式,自動(dòng)將其轉(zhuǎn)化為數(shù)據(jù)框(Dataframe)。

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

      顯示效果如下:

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

      CSV/TSV

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

      • csv :逗號(hào)分隔數(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ù)值型索引也會(huì)一起寫到 csv 文件里面去。對(duì)我們來說,這沒有必要,會(huì)白白占用存儲(chǔ)空間。

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

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

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

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

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

      我們?cè)囋嚳础?/p>

      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 。我們還是在編輯器里面打開它看看。

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

      大體上二者差不多。

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

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

      為什么呢?

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

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

      我們?cè)囍?Pandas 把它讀取回來。

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

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

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

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

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

      別忙,我們?cè)賮砜匆粋€(gè)使用案例。

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

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

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

      !pip install jieba

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

      import jieba

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

      怎么辦呢?

      我們來編寫一個(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 上存儲(chǔ)的確實(shí)是個(gè)列表呢?

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

      df_list.text.iloc[0][0]

      結(jié)果顯示為:

      '這'

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

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

      先嘗試 csv 格式。

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

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

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

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

      至于分割符嘛,依然是逗號(hào)。

      看著是不是很正常?

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

      pd.read_csv('data_list.csv')

      結(jié)果是這樣的:

      初看起來,很好?。?/p>

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

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

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

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

      然而,我們需要驗(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 格式是不是對(duì)我們的問題有幫助。

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

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

      列表就是列表,兩邊并沒有用雙引號(hào)包裹。

      這次興許能成!

      我們趕緊讀回來看看。

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

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

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

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

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

      果不其然,還是中括號(hào)。

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

      任務(wù)失敗。

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

      那我們?cè)撛趺崔k呢?

      pickle

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

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

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

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

      df_list.to_pickle('data.pickle')

      讀取回來,也很方便。

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

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

      df_list_loaded

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

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

      df_list_loaded.text.iloc[0][0]

      結(jié)果是:

      '這'

      很讓人欣喜的結(jié)果?。?/p>

      看來 pickle 格式果然靠譜。

      不過,當(dāng)我們?cè)噲D在文本編輯器里打開 pickle 格式的時(shí)候,會(huì)有警告。

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

      只不過,你看得懂嗎?

      反正我是看不懂的。

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

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

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

      我們?cè)谧鰯?shù)據(jù)分析的時(shí)候,難免會(huì)調(diào)用 Pandas 以外的軟件包,繼續(xù)分析我們用 Pandas 預(yù)處理后的文件。

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

      一個(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 絕對(duì)是數(shù)據(jù)交換界的一等公民。

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

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

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

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

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

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

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

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

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

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

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

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

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

      看看讀入效果:

      df_list_loaded_json

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

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

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

      df_list_loaded_json.text.iloc[0][0]

      顯示為:

      '這'

      太棒了!

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

      小結(jié)

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

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

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

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

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

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

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

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

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多