目前在煙草物流中心的項(xiàng)目規(guī)劃及設(shè)計(jì)中廣泛應(yīng)用的數(shù)據(jù)分析工具主要有Excel、R、SQL Server等。其中,Excel對(duì)可處理的數(shù)據(jù)行、列數(shù)都有明顯限制。以Excel 2016版為例,最多可處理1048576行、16384列的數(shù)據(jù),更適用于小型數(shù)據(jù)的簡(jiǎn)單分析;而商業(yè)軟件SQL Server的可伸縮性有限,當(dāng)多用戶連接時(shí)性能會(huì)變差,更適用于數(shù)據(jù)類型相對(duì)規(guī)整的中小型數(shù)據(jù);R在統(tǒng)計(jì)方面表現(xiàn)突出,但處理上GB數(shù)據(jù)時(shí)的運(yùn)行速度較為緩慢,對(duì)于數(shù)據(jù)類型復(fù)雜的大型數(shù)據(jù)來說,其內(nèi)含包如data.table、smartdata、cleanerR等也不如Python的工具集使用靈活。
Python作為一款免費(fèi)的開源軟件,在Windows、MacOS、Linux等操作系統(tǒng)中都有其對(duì)應(yīng)的版本,具有代碼簡(jiǎn)潔、可讀性高等優(yōu)勢(shì),其中的pandas工具集提供了大量處理數(shù)據(jù)的函數(shù)和方法,用于數(shù)據(jù)挖掘和數(shù)據(jù)分析,同時(shí)也提供數(shù)據(jù)清洗功能。pandas擁有更高的數(shù)據(jù)交換性,對(duì)xlsx、csv、mdf、txt、html等格式數(shù)據(jù)提供統(tǒng)一的導(dǎo)入模塊,并轉(zhuǎn)換為DataFrame格式數(shù)據(jù);通過參數(shù)設(shè)置既能導(dǎo)入少量的數(shù)據(jù)進(jìn)行預(yù)覽,又能只導(dǎo)入需求的列進(jìn)行分析;具有良好的交互模式,可以一個(gè)命令即時(shí)返回一個(gè)結(jié)果,也可以一次性運(yùn)行所有命令得到最終結(jié)果;此外,煙草物流中心的訂單分批現(xiàn)象給處理日期數(shù)據(jù)增加了難度,pandas則可以自動(dòng)解析目標(biāo)列中類似日期格式的數(shù)據(jù),為以日期為分組依據(jù)的數(shù)據(jù)聚合運(yùn)算提供便利。
數(shù)據(jù)處理為數(shù)據(jù)分析及方案規(guī)劃打下基礎(chǔ),原始數(shù)據(jù)中一般會(huì)含有大量冗余數(shù)據(jù),比如同時(shí)存在條煙編號(hào)列和條煙名稱列,且為一一對(duì)應(yīng)關(guān)系,在導(dǎo)入數(shù)據(jù)時(shí),只需保留數(shù)值型的條煙編號(hào)列以減少內(nèi)存占用;再比如數(shù)據(jù)中含有多列關(guān)于客戶信息的數(shù)據(jù)、且每一列都無法作為客戶信息識(shí)別的唯一標(biāo)識(shí)時(shí),在保證其對(duì)應(yīng)關(guān)系的前提下將幾列或所有關(guān)于客戶信息的數(shù)據(jù)列合并成為新的一列,并指定為“客戶編號(hào)”,用作唯一標(biāo)識(shí)客戶信息的數(shù)據(jù)列。因此在數(shù)據(jù)分析前,一般會(huì)先根據(jù)需求設(shè)定目標(biāo)列,然后導(dǎo)入對(duì)應(yīng)的原始數(shù)據(jù),最后對(duì)數(shù)據(jù)進(jìn)行清洗和整理。
對(duì)煙草物流中心的銷售數(shù)據(jù)進(jìn)行處理時(shí),通常把目標(biāo)列設(shè)為:訂單日期、訂單編號(hào)、客戶編號(hào)、品規(guī)及銷售數(shù)量等,如果需要區(qū)分異型煙,可再多增加一列異型煙標(biāo)記列。
本文以某煙草物流中心一年的實(shí)際銷售數(shù)據(jù)data2020.csv為例,詳細(xì)說明如何使用pandas 0.24.2版來實(shí)現(xiàn)數(shù)據(jù)的導(dǎo)入、基本清洗及整理。
由于pandas是Python的工具集之一,正常情況下,在使用前都需要安裝大量的工具包,安裝步驟也非常復(fù)雜,而使用基于Python的Anaconda Navigator軟件作為數(shù)據(jù)處理工具可以避免上述問題。Anaconda Navigator是一個(gè)開源的集成了大量工具包的工具合集,可以一次性安裝所有運(yùn)行Python時(shí)需要的各種工具包,降低了安裝難度。
打開Anaconda Navigator中的Jupyter Notebook,在原始數(shù)據(jù)data2020.csv所在文件夾中新建一個(gè)Jupyter Notebook工程文件,利用import pandas as pd命令導(dǎo)入所需的pandas工具集。
數(shù)據(jù)預(yù)覽是在正式導(dǎo)入數(shù)據(jù)前,對(duì)數(shù)據(jù)進(jìn)行的簡(jiǎn)單查看,其主要有兩個(gè)目的:一是確認(rèn)數(shù)據(jù)是否可以使用pandas進(jìn)行導(dǎo)入;二是查看是否含有不需要導(dǎo)入的冗余數(shù)據(jù)列,以及是否有需要進(jìn)行合并等二次處理的數(shù)據(jù)列。
大部分?jǐn)?shù)據(jù)分析軟件不具備數(shù)據(jù)預(yù)覽的功能,只能一次性導(dǎo)入所有數(shù)據(jù),一旦報(bào)錯(cuò)就會(huì)被迫終止導(dǎo)入。而pandas工具集在這一方面存在天然的優(yōu)勢(shì),可通過參數(shù)設(shè)置導(dǎo)入指定行數(shù)據(jù)來對(duì)原始數(shù)據(jù)進(jìn)行實(shí)驗(yàn)性導(dǎo)入,幫助我們對(duì)數(shù)據(jù)建立基本認(rèn)識(shí)。
pandas中提供了多種導(dǎo)入數(shù)據(jù)的函數(shù),并且都可以實(shí)現(xiàn)預(yù)覽目的,可根據(jù)不同數(shù)據(jù)格式選擇對(duì)應(yīng)的導(dǎo)入函數(shù)。本文使用pd.read_csv()函數(shù)及其提供的部分參數(shù)實(shí)現(xiàn)對(duì)數(shù)據(jù)的預(yù)導(dǎo)入,參數(shù)如下:
nrows:設(shè)置導(dǎo)入行數(shù),例如nrows=5,通過查看前五行數(shù)據(jù),快速判斷數(shù)據(jù)是否存在編碼、格式等問題,以及是否需要導(dǎo)入所有列;
skiprows:設(shè)置需要忽略的行數(shù)或要跳過的行號(hào)列表,當(dāng)樣本數(shù)量很大時(shí),可結(jié)合函數(shù)進(jìn)行隨機(jī)抽取,比如隨機(jī)抽取1%的行數(shù)。
圖1 編碼格式報(bào)錯(cuò)
圖2 數(shù)據(jù)預(yù)覽
圖3 數(shù)據(jù)導(dǎo)入結(jié)果
在上文新建的Jupyter Notebook文件中,導(dǎo)入data2020.csv的前五行數(shù)據(jù)預(yù)覽并將其命名為“df”,代碼如下:
返回結(jié)果,如圖1。
由圖1可知,因?yàn)槲募陨淼木幋a與pandas默認(rèn)采用的“utf-8”解碼方式不相符,從而使“utf-8”編碼解碼器無法解碼該數(shù)據(jù),所以返回報(bào)錯(cuò)提示,可通過添加參數(shù)encoding來解決。在含有中文編碼的情況下,除常用的“gbk”編解碼器外,還有“gb18030”、“hz”、“big5”等。
修改代碼如下:
運(yùn)行后,系統(tǒng)不再報(bào)錯(cuò),使用df.head()函數(shù)查看成功導(dǎo)入的前五行數(shù)據(jù),返回結(jié)果如圖2。
因此,在正式導(dǎo)入數(shù)據(jù)前,利用參數(shù)nrows或skiprows進(jìn)行數(shù)據(jù)預(yù)導(dǎo)入,可避免因編解碼器錯(cuò)誤、數(shù)據(jù)類型復(fù)雜等問題帶來的重復(fù)操作,以提高數(shù)據(jù)導(dǎo)入效率。
通過簡(jiǎn)單預(yù)覽,我們可得出:
(1)該數(shù)據(jù)沒有列名;
(2)第七列產(chǎn)品名稱列與第六列產(chǎn)品編號(hào)列含義相同,因此第七列可當(dāng)做冗余數(shù)據(jù),無需導(dǎo)入,以加快速度、節(jié)省內(nèi)存占用;
(3)前三列分別代表年、月、日,可合并為新的一列并轉(zhuǎn)換為日期格式。
但完整數(shù)據(jù)中可能還會(huì)存在預(yù)覽中無法看出的問題,比如是否存在缺失值、異常值等問題,需要在導(dǎo)入所有行數(shù)據(jù)后再進(jìn)行判斷。
以上主要介紹了pd.read_csv()函數(shù)中常用于數(shù)據(jù)預(yù)覽的兩個(gè)參數(shù),本章中繼續(xù)使用此函數(shù)中的以下參數(shù)對(duì)數(shù)據(jù)進(jìn)行正式導(dǎo)入,并解決列名及冗余數(shù)據(jù)問題,減少導(dǎo)入的數(shù)據(jù)量,加快數(shù)據(jù)處理速度:
usecols:設(shè)置導(dǎo)入指定列,可以是列名或?qū)?yīng)的索引值。在此數(shù)據(jù)中,以目標(biāo)列為基礎(chǔ)導(dǎo)入,需要導(dǎo)入的列索引值為:usecols=[0,1,2,3,4,5,7,8];
header:指定第幾行作為列名稱,默認(rèn)為0,若如本文中數(shù)據(jù)需要另外指定列名,此參數(shù)設(shè)置為None;
names:指定列名,當(dāng)header=None時(shí),添加此參數(shù)設(shè)置列名。
綜上,數(shù)據(jù)導(dǎo)入代碼如下:
查看返回結(jié)果,如圖3。
由圖3結(jié)果可知,目標(biāo)列數(shù)據(jù)已導(dǎo)入且命名成功,數(shù)據(jù)預(yù)覽中的問題也得到解決。但返回一個(gè)第0列及第5列為混合類型的警示:因?yàn)樵趐andas內(nèi)部以塊的形式處理文件,會(huì)降低解析時(shí)的內(nèi)存使用量,但如果在一列中有不止一個(gè)數(shù)據(jù)類型存在時(shí),將被系統(tǒng)判斷為混合類型并返回此警示,可以設(shè)置“l(fā)ow_memory=False”,或利用dtype參數(shù)指定每列的數(shù)據(jù)類型,但會(huì)占用大量?jī)?nèi)存和時(shí)間,可以等數(shù)據(jù)全部導(dǎo)入后再進(jìn)行列數(shù)據(jù)類型的指定。
通過df.head()函數(shù)查看數(shù)據(jù)前五行發(fā)現(xiàn):數(shù)據(jù)中的“month”、“day”、“qty”及“customer_code”等四列均被轉(zhuǎn)換為浮點(diǎn)類型,由于pandas不支持存儲(chǔ)含有缺失值的整型及布爾型數(shù)組,當(dāng)引入含有缺失值的整型數(shù)組時(shí),根據(jù)pandas對(duì)數(shù)據(jù)的處理規(guī)則,該列數(shù)據(jù)將被轉(zhuǎn)換為浮點(diǎn)型,因此可以推斷出這四列數(shù)據(jù)中可能含有缺失值,需要進(jìn)行單獨(dú)驗(yàn)證。
至此數(shù)據(jù)導(dǎo)入工作已經(jīng)完成,除導(dǎo)入本文數(shù)據(jù)需要的參數(shù)外,pd.read_csv()函數(shù)中還有許多其他常用參數(shù)可以在導(dǎo)入數(shù)據(jù)時(shí)快速設(shè)置:
sep:指定分隔符,若其他非逗號(hào)分隔符的文件,也可以通過修改該參數(shù)導(dǎo)入;
index_col:指定列數(shù)據(jù)作為行索引,默認(rèn)值為None;
na_filter:默認(rèn)為True,是否檢查丟失值(空字符串或空值),在沒有任何缺失值的數(shù)據(jù)中,傳遞參數(shù)na_filter=False可提高讀取大文件的速度;
skip_blank_lines:默認(rèn)為True,忽略空白行而不是解析為NaN;
error_bad_lines:默認(rèn)為True,若有含大量字段的行(例如大量逗號(hào))在默認(rèn)情況下會(huì)引發(fā)異常,并且不會(huì)返回任何DataFrame,若error_bad_lines=False,這些“異常行”將不被導(dǎo)入;
warn_bad_lines:默認(rèn)為True,如果上一個(gè)參數(shù)設(shè)為False,而warn_bad_lines=True,則將為每個(gè)“異常行”輸出警告;
圖4 info()函數(shù)返回值
圖5 提取缺失值
圖6 刪除缺失值
parse_dates:指定一列或多列字符串合并解析為日期格式。
數(shù)據(jù)處理是在數(shù)據(jù)成功導(dǎo)入后,對(duì)數(shù)據(jù)進(jìn)行的缺失值及無效值清洗、數(shù)據(jù)類型轉(zhuǎn)換、日期格式處理等一系列操作,以達(dá)到規(guī)整數(shù)據(jù)的目的,為接下來的數(shù)據(jù)分析做準(zhǔn)備。
利用pandas對(duì)數(shù)據(jù)處理之前,可以先通過info()函數(shù)查看數(shù)據(jù)的詳細(xì)信息,例如數(shù)據(jù)類型、空值及內(nèi)存占用情況等,info()函數(shù)中的常用參數(shù)有以下幾個(gè):
圖7 轉(zhuǎn)換類型及結(jié)果查詢
(1)本數(shù)據(jù)共14023517行,除“year”列以外的其他列都只含有14023515個(gè)非空值行,說明除“year”列以外的其他列中都含有2個(gè)空值;
圖8 數(shù)據(jù)描述結(jié)果
圖9 提取負(fù)值
圖10 數(shù)據(jù)保存圖
(2)數(shù)據(jù)類型存在問題,例如“year”、“month”、“day”和“qty”列應(yīng)轉(zhuǎn)換為int整型,“customer_code”列在預(yù)覽導(dǎo)入中可見共12位整數(shù),應(yīng)轉(zhuǎn)換為int64整型;
(3)內(nèi)存占用為3.4GB,其中,最后一列數(shù)據(jù)為異型煙標(biāo)識(shí)列,代表是否為異型煙,存在大量重復(fù)字段且唯一值少,可目錄化為category類型,不但可以繼續(xù)顯示原內(nèi)容為閱讀提供方便,而且可以在占用更少內(nèi)存的同時(shí)兼顧運(yùn)行速度。
在已經(jīng)導(dǎo)入的原始數(shù)據(jù)中可能會(huì)存在少量缺失值,這會(huì)使某些函數(shù)及代碼無法運(yùn)行或增加其運(yùn)行時(shí)長(zhǎng),例如使用to_datetime()函數(shù)將某列或某幾列轉(zhuǎn)換為日期格式時(shí),當(dāng)數(shù)據(jù)中存在缺失值時(shí)就會(huì)報(bào)錯(cuò)。因此,為使數(shù)據(jù)分析結(jié)果的準(zhǔn)確性更高,需要對(duì)這些可能存在的缺失值進(jìn)行優(yōu)先處理。
首先利用isnull()函數(shù)和any()函數(shù)提取數(shù)據(jù)中的缺失值,設(shè)置any()函數(shù)中的參數(shù)axis=1選取含有缺失值的行,觀察其分布情況,判斷缺失值是否對(duì)數(shù)據(jù)分析結(jié)果有影響,使用代碼如下:
df[df.isnull().any(axis=1)]
查看返回結(jié)果,如圖5。
由圖5可知,除“year”列以外的其他列中的缺失值均位于14023515和14023516兩行,在判定不影響整體分析結(jié)果的情況下,將此兩行數(shù)據(jù)刪除;若缺失值較多或?qū)?shù)據(jù)分析結(jié)果有影響,則需根據(jù)實(shí)際情況對(duì)缺失值進(jìn)行填充。
接下來再利用dropna()函數(shù)刪除缺失值,相關(guān)參數(shù)如下:
how:當(dāng)整行或整列中有至少一個(gè)缺失值或全為缺失值時(shí),通過此設(shè)置確定刪除方法,默認(rèn)“any”,刪除存在缺失值的行或列;“all”,刪除全為缺失值的行或列;
axis:確定按行向下判斷還是按列向右判斷,默認(rèn)axis=0,按行向下判斷;
inplace:默認(rèn)False,若inplace=True,直接在原始數(shù)據(jù)上進(jìn)行;
subset:刪除指定列中含有缺失值的行或指定行中含有缺失值的列。
刪除缺失值并查看結(jié)果,代碼如下:
memory_usage:是否顯示DataFrame中所有元素(包括索引)的總內(nèi)存使用情況,“True”,始終顯示內(nèi)存情況,“False”不顯示內(nèi)存情況,“deep”,精確計(jì)算內(nèi)存使用情況;
null_counts:是否顯示非空計(jì)數(shù),“True”,始終顯示非空數(shù)量,“False”,不顯示非空數(shù)量。
使用代碼如下:
查看返回結(jié)果,如圖4。
由圖4可知:
返回結(jié)果,如圖6。
由圖6可知,再次運(yùn)行df.info()函數(shù)后所有列的行數(shù)相同,說明數(shù)據(jù)中已無缺失值。
在pandas中通常利用astype()函數(shù)實(shí)現(xiàn)對(duì)數(shù)據(jù)類型的轉(zhuǎn)換,先返回一個(gè)結(jié)果作為預(yù)覽,并不會(huì)改變?cè)紨?shù)據(jù),因此在轉(zhuǎn)換時(shí)可先運(yùn)行代碼查看轉(zhuǎn)換結(jié)果,確認(rèn)無誤后再通過賦值的方法對(duì)原始數(shù)據(jù)進(jìn)行更改。
按照上文中提到的分別將“year”、“month”、“day”和“qty”列轉(zhuǎn)換為int整型,“customer_code”列轉(zhuǎn)換為int64整型,“special_type”列轉(zhuǎn)換為category類型,代碼如下:
全部數(shù)據(jù)列類型轉(zhuǎn)換成功后,繼續(xù)運(yùn)行代碼df.info()函數(shù)查看內(nèi)存占用情況,返回結(jié)果如圖7。
由圖7可知,轉(zhuǎn)換后的內(nèi)存占用為1.8GB,比轉(zhuǎn)換前減少了47%,因此在分析大型數(shù)據(jù)前盡量把中文字符處理成占用字節(jié)更少的數(shù)據(jù)類型,可有效減小內(nèi)存占用,提升運(yùn)行速度。
除上述操作以外,數(shù)據(jù)中可能還存在異常值,比如本文數(shù)據(jù)中的“month”列中是否有大于12的數(shù)值,比如“day”列是否有大于31的數(shù)值,再比如“qty”列中是否有零或負(fù)值等,可以使用df.select_dtypes()函數(shù)來提取上述可能含有異常值的整形列并判斷其最值情況,代碼如下:
圖11 日期設(shè)為索引
圖12 方式一運(yùn)行
圖13 方式二運(yùn)行
圖14 數(shù)據(jù)保存圖
返回結(jié)果如圖8。
由圖8可知,只有“qty”列的最小值為-50,不符合實(shí)際情況,利用代碼“df[df['qty']<=0]”將“qty”列中所有小于或等于零的數(shù)據(jù)全部提取出來,返回結(jié)果如圖9。
由圖9可知,“qty”列中只存在一個(gè)負(fù)值,由于負(fù)值的數(shù)量很少,可直接作為異常值進(jìn)行刪除,或根據(jù)實(shí)際分析需求進(jìn)行處理。
在分析基于時(shí)間序列的數(shù)據(jù)時(shí),經(jīng)常會(huì)碰到日期格式處理和轉(zhuǎn)換問題,而pandas有著強(qiáng)大的日期數(shù)據(jù)處理功能,將其設(shè)置為整個(gè)數(shù)據(jù)的索引,更方便于利用resample()函數(shù)對(duì)數(shù)據(jù)進(jìn)行頻率轉(zhuǎn)換和時(shí)間序列重采樣等操作。下文將介紹兩種情況下將數(shù)據(jù)轉(zhuǎn)換為日期格式的方法:
(1)中小型數(shù)據(jù)集
運(yùn)用read_csv()函數(shù)中參數(shù)parse_dates,在導(dǎo)入數(shù)據(jù)時(shí)直接將一列(如20181018、2018-10-18、2018/10/18等)或多列數(shù)據(jù)合并解析(以本文數(shù)據(jù)為例parse_dates={'date':['year','month','day']}),可快速將數(shù)據(jù)轉(zhuǎn)換為日期格式。但該方法在解析時(shí)間格式時(shí)對(duì)內(nèi)存占用較大,數(shù)據(jù)導(dǎo)入時(shí)間較長(zhǎng),且如果待解析列格式不統(tǒng)一或存在空值、異常值時(shí),將不會(huì)轉(zhuǎn)換為日期格式,只能作為普通數(shù)值類型返回,因此這個(gè)方法常適用于數(shù)據(jù)量較小的情況。
(2)大型數(shù)據(jù)集
當(dāng)數(shù)據(jù)量很大且日期格式不標(biāo)準(zhǔn)時(shí),可以在導(dǎo)入目標(biāo)數(shù)據(jù)后,使用to_datetime()函數(shù)將DataFrame中指定的一列或幾列合并后轉(zhuǎn)換為datetime日期格式,且to_datetime可以解析多種不同的日期表示形式,常用參數(shù)如下:
errors:對(duì)錯(cuò)誤的處理方式,默認(rèn)為“raise”,無效解析將返回異常;“coerce”,無效解析設(shè)置為NaT;“ignore”,忽略無效解析返回輸入值;
dayfirst:當(dāng)待解析的對(duì)象為字符串或列表時(shí),指定日期解析順序,默認(rèn)為False,若為True,優(yōu)先解析day,例如10/11/12將被解析為2012-11-10;
yearfirst:與dayfirst同理,若為True,優(yōu)先解析year,例如10/11/12將被解析為2010-11-12;
format:指定日期格式。
在本文數(shù)據(jù)中處理日期格式數(shù)據(jù)過程代碼如下:
返回結(jié)果,如圖10和圖11。
為更直觀的感受上述兩種方式在運(yùn)行速度上的差別,新建一個(gè)Jupyter Notebook文件并導(dǎo)入pandas,借助%time函數(shù)來分別計(jì)算兩種方式的代碼運(yùn)行時(shí)間。本文用于實(shí)現(xiàn)的電腦基本配置為:Windows 7 64位操作系統(tǒng)、Intel Xeon CPU E5-1650 V3處理器、16G內(nèi)存、128G固態(tài)硬盤。
第一種方式的代碼如下:
運(yùn)行結(jié)果,如圖12。
第二種方式的代碼如下:
運(yùn)行結(jié)果,如圖13。
由圖12可知,第一種方式先用上文中提到的parse_dates參數(shù)合并日期列,再導(dǎo)入完整數(shù)據(jù)的所用時(shí)長(zhǎng)為27分15秒;由圖13可知,第二種方式先直接導(dǎo)入數(shù)據(jù),然后再分步處理日期得到與第一種方式的相同結(jié)果,需要注意的是在上文中已知數(shù)據(jù)存在空值行,為避免to_datetime()函數(shù)報(bào)錯(cuò),在合并日期數(shù)據(jù)前,先對(duì)空值行進(jìn)行刪除,所有代碼的運(yùn)行時(shí)間加和約為45秒。綜上所述,對(duì)于含有需要合并的日期列且數(shù)據(jù)量大的數(shù)據(jù)來說,采用第一種方式雖然可以一次性解決日期數(shù)據(jù)問題,但邏輯不如第二種清晰,且讀取csv文件的時(shí)間成倍增加,大約是第二種方式的36倍,此時(shí)優(yōu)先選擇第二種方式更能節(jié)省整體的處理時(shí)間。
pandas工具集不但可以導(dǎo)入多種格式的數(shù)據(jù),而且能根據(jù)數(shù)據(jù)處理情況將數(shù)據(jù)保存成多種格式。
若數(shù)據(jù)未處理完,可保存為hdf格式來快速暫存數(shù)據(jù)處理的中間結(jié)果。在將hdf格式數(shù)據(jù)保存到硬盤的過程中,會(huì)保留數(shù)據(jù)在內(nèi)存中的排列順序,以及列數(shù)據(jù)的格式類型,數(shù)據(jù)的保存和讀取速度都十分迅速。
若數(shù)據(jù)已經(jīng)完成處理,可保存為txt、hdf、csv等格式,其中csv格式數(shù)據(jù)可以被大多數(shù)電子表格和數(shù)據(jù)庫(kù)系統(tǒng)支持,具有較高的通用性,因此將本文中處理好的數(shù)據(jù)也保存為csv格式數(shù)據(jù)。
pandas中一般使用df.to_csv()函數(shù)將已處理好的數(shù)據(jù)保存成csv格式,常用參數(shù)如下:
sep:指定分隔符,csv文件默認(rèn)為逗號(hào),若其他非逗號(hào)分隔符的文件,也可以通過修改該參數(shù)保存;
header:是否保存列名,默認(rèn)為True,當(dāng)值設(shè)為零時(shí),不保存列名;
index:是否保存索引,默認(rèn)為True,當(dāng)值設(shè)為False時(shí),不保存索引;
index_label:設(shè)置索引對(duì)應(yīng)的列名,默認(rèn)為None;
encoding:設(shè)置編碼方式,默認(rèn)編碼方式為utf-8。
保存本文整理好的df數(shù)據(jù),并將其命名為“data2020-1”,代碼如下:
df.to_csv('data2020-1.csv')
數(shù)據(jù)保存結(jié)果,如圖14。
由圖14可知,處理后的數(shù)據(jù)不但文件大小得到改善,而且具有更高的交換性及準(zhǔn)確性,可以直接用其他數(shù)據(jù)分析軟件或仿真軟件進(jìn)行數(shù)據(jù)分析,也可以繼續(xù)用pandas分析,節(jié)省導(dǎo)入時(shí)間的同時(shí)提高效率。
本文通過使用pandas對(duì)煙草物流中心的實(shí)際銷售數(shù)據(jù)進(jìn)行導(dǎo)入、清洗、整理工作,將類型不規(guī)則、存在缺失值的數(shù)據(jù)規(guī)整為數(shù)據(jù)類型固定且只含有目標(biāo)列的數(shù)據(jù),為數(shù)據(jù)分析、挖掘及可視化奠定基礎(chǔ)。從導(dǎo)入和處理過程中可以看出,基于Python編程語(yǔ)言的pandas工具集的代碼可讀性更高,可以快速簡(jiǎn)便地實(shí)現(xiàn)少量行數(shù)據(jù)或需求列數(shù)據(jù)的導(dǎo)入,導(dǎo)入速度也優(yōu)于其他數(shù)據(jù)分析工具,其中內(nèi)置的函數(shù)和方法可以更加高效的對(duì)大型數(shù)據(jù)集進(jìn)行處理。但由于pandas處理數(shù)據(jù)時(shí)是把數(shù)據(jù)存儲(chǔ)于計(jì)算機(jī)的內(nèi)存中,如果數(shù)據(jù)量太大,比如數(shù)據(jù)量高達(dá)幾百GB時(shí),考慮內(nèi)存限制也不適合用pandas工具集進(jìn)行導(dǎo)入。煙草物流中心規(guī)劃項(xiàng)目的特殊性使不同項(xiàng)目的原始數(shù)據(jù)間存在一定的相似性,因此引用的函數(shù)和方法可以對(duì)不同項(xiàng)目的原始數(shù)據(jù)進(jìn)行重復(fù)使用,也可以利用其編程語(yǔ)言的靈活性,針對(duì)特殊問題編寫個(gè)性化的函數(shù)使用,提高工作效率,具有良好的通用性和實(shí)用性。