標籤:隨機數組 功能 有一個 其他 系統 先來 資料 優點 固定
資料的檢索、加工與儲存1.利用Numpy和pandas對CSV檔案進行寫操作
對CSV檔案進行寫操作,numpy的savetxt()函數是與loadtxt()相對應的一個函數,他能以諸如CSV之類的區隔型檔案格式儲存數組:
np.savetxt(‘np.csv‘,a,fmt=‘%.2f‘,delimiter=‘,‘,header="#1,#2,#3,#4")
上面的函數調用中,我們規定了用以儲存數組的檔案的名稱、數組、可選格式、間隔符(預設為空白格符)和一個可選的標題。
利用隨機數組來建立pandas DataFrame,如下:
df=pd.DataFrame(a)
利用pandas的to_csv()方法可以為CSV檔案產生一個DataFrame
df.to_csv(‘pd.csv‘,float_format=‘%.2f‘,na_rep="NAN!")
對於這個方法,我們需要提供檔案名稱、類似於Numpy的savetxt()函數的格式化參數的可選格式串和一個表示NaN的可選字串
2.Numpy.npy與pandas DataFrame
大部分情況下,用CSV格式來儲存檔案是不錯的主意,因為大部分程式設計語言和應用程式都能處理這種格式,所以交流起來非常方便。然而,這種格式有一個缺陷,就是它的儲存效率不是很高,原因是CSV及其他純文字格式中含有大量空白符;而後來發明的一些檔案格式,如zip、bzip和gzip等,壓縮率則有了顯著提升。
import numpy as npimport pandas as pdfrom tempfile import NamedTemporaryFilefrom os.path import getsizenp.random.seed(42)a=np.random.randn(365,4)tmpf=NamedTemporaryFile()np.savetxt(tmpf,a,delimiter=‘,‘)print("Size CSV file",getsize(tmpf.name))tmpf=NamedTemporaryFile()np.save(tmpf,a)tmpf.seek(0)loaded=np.load(tmpf)print("shape",loaded.shape)print("Size .npy file",getsize(tmpf.name))df=pd.DataFrame(a)df.to_pickle(tmpf.name)print("Size pickled dataframe",getsize(tmpf.name))print("DF from pickle\n",pd.read_pickle(tmpf.name))
Numpy為自己提供了一種專用的格式,稱為.女朋友,可以用於儲存Numpy數組。在進一步說明這種格式之前,我們先來產生一個365×4d的Numpy數組,並給各個元素填充上隨機值。這個數組可以看成是一年中4個隨機變數的每日觀測值的類比。這裡我們使用Python標準的NamedTemporaryFile來儲存資料,這些臨時檔案隨後會自動刪除。
下面將該數組存入一個CSV檔案,並檢查其大小,代碼如下:
tmpf=NamedTemporaryFile()np.savetxt(tmpf,a,delimiter=‘,‘)print("Size CSV file",getsize(tmpf.name))
下面首先以Numpy.npy格式來儲存該數組,隨後載入記憶體,並檢查數組的形狀以及該.npy檔案的大小,具體代碼如下所示:
tmpf=NamedTemporaryFile()np.save(tmpf,a)tmpf.seek(0)loaded=np.load(tmpf)print("shape",loaded.shape)print("Size .npy file",getsize(tmpf.name))
為了類比該臨時檔案的關閉與重新開啟過程,我們在上面的代碼中調用了seek()函數。數組的形狀以及檔案大小如下所示:
Shape(365,4)Size .npy file 11760
不出所料,.npy檔案的大小隻有CSV檔案的1/3左右。實際上,利用Python可以儲存任意複雜的資料結構。也可以序列化格式來儲存pandas的DataFrame或者Series資料結構。
提示:
在Python中,pickle是將PythonObject Storage Service到磁碟或其他介質時採用的一種格式,這個格式化的過程叫做序列化(pickling).之後,我們可以從儲存空間中重建該Python對象,這個逆過程稱為還原序列化(unpickling).
首先用前面產生的Numpy數組建立一個DataFrame,接著用to_pickle()方法將其寫入一個pickle對象中,然後用read_pickle()函數從這個pickle對象中檢索該DataFrame:
df=pd.DataFrame(a)df.to_pickle(tmpf.name)print("Size pickled dataframe",getsize(tmpf.name))print("DF from pickle\n",pd.read_pickle(tmpf.name))
該DataFrame經過序列化後,尺寸略大於.npy檔案。
3.使用PyTables 儲存資料
層次資料格式(HDF)是一種儲存大型數值資料的技術規範,起源於超級計算社區,目前已經成為一種開放的標準。這裡用HDF5,該版本僅僅通過組(group)和資料集(dataset)這兩種基本結構來組織資料。資料集可以是同類型的多維陣列,而組可以用來存放其他組或者資料集。這裡的“組”跟層次式檔案系統中的“目錄”非常像。
HDF5最常見的兩個主要Python程式庫是:
1.h5y
2.PyTables
本例中使用的是PyTables。不過,這個程式庫需要用到一些依賴項,比如:
1.Numpy
2.numexpr:該程式包在計算包含多種運算的數組運算式時,其速度要比Numpy快許多倍
3.HDF5:如果使用HDF5的並行版本,則還需要安裝MPI.
據Numexpr自稱,它在某些方面的運算速度要比Numpy快得多,因為它支援多線程,並且自己得虛擬機器是C語言實現得。
此外,我們需要產生一些隨機數,並用它們來給一個Numpy數組賦值。下面建立一個HDF5檔案,並把這個Numpy數組掛載到根結點上
from tempfile import NamedTemporaryFileimport numpy as npfrom os.path import getsizea=np.random.randn(365,4)tmpf=NamedTemporaryFile()h5file=tables.openfile(tmpf.name,mode=‘w‘,title="Numpy Array")root=h5file.rooth5file.createArray(root,"array",a)h5file.close()#讀取這個HDF5,並顯示檔案大小h5file=tables.openfile(tmpf.name,"r")print(getsize(tmpf.name))
通過遍曆取為裡面的資料
for node in h5file.iterNodes(h5file.root): b=node.read() print(type(b),b.shape)
4.Pandas DataFrame與HDF5倉庫之間的讀寫操作
HDFStore類可以看作是pandas中負責HDF5資料處理部分的一種抽象。藉助一些隨機資料和臨時檔案,可以很好地展示這個類地功能特性,具體步驟如下所示:
將臨時檔案地路徑傳遞給HDFStore的建構函式,然後建立一個倉庫:
store=pd.io.pytables.HDFStore(tmpf.name)print(store)
上述代碼將列印輸出該倉庫的檔案路徑及其內容,不過,此刻他還沒有任何內容。
HDFStore提供了一個類似字典類型的介面,如我們可以通過pandas中DataFrame的查詢鍵來儲存數值。為了將包含隨機資料的一個DataFrame儲存到HDFStore中,可以使用下列代碼:
store[‘df‘]=dfprint(store)
我們可以用三種方式來訪問DataFrame,分別是:使用get()方法訪問資料,利用類似字典的查詢鍵訪問資料,或者使用點運算子號來訪問資料:
print("Get",store.get(‘df‘).shape)print("Lookup",store[‘df‘].shape)print("Dotted",store.df.shape)
該DataFrame的形狀同樣也可以通過3種不同的方式進行訪問
為了刪除倉庫中的資料,我們既可以使用remove()方法,也可以使用del運算子。當然,每個資料只能刪除一次。
del store[‘df‘]
屬性 is_open的作用是指出倉庫是否處於開啟狀態。為了關閉一個倉庫,可以調用close()方法。下面代碼展示關閉倉庫的方法,並針對倉庫的狀態進行了相應的檢查:
print("Before close",store.is_open)store.close()print("After close",store.is_open)
為讀寫HDF資料,pandas還提供了兩種方法:一種是DataFrame的to_hdf()方法;另一種是頂級的read_hdf()函數。
df.to_hdf(tmpf.name,‘data‘,format=‘table‘)print(pd.read_hdf(tmpf.name,‘data‘,where=[‘index>363‘]))
用於讀寫操作的應用程式介面的參數包括:檔案路徑、倉庫中組的標識符以及可選的格式串。這裡的格式有兩種:一種是固定格式;一種是表格格式。固定格式的優點是速度要更快一些,缺點是無法追加資料,也不能進行搜尋。表格格式相當於PyTables的Table結構,可以對資料進行搜尋和選擇操作。
5.使用pandas讀寫Excel檔案
現實中許多重要資料都是以Excel檔案的形式存放的。當然,如果需要,也可以將其轉換為可移植性更高的諸如CSV之類的格式。不過,利用Python來操作Excel檔案會更加方便。在Python的世界裡,為實現同一目標的項目通常不止一個,如提供Excel I/O操作功能的項目就是如此。只要安裝了這些模組,就能讓pandas具備讀寫Excel檔案的能力,只是這些方面的說明文檔不是很完備,其原因是pandas依賴的這些項目往往各自為戰,並且發展極為迅猛。這些pandas程式包對於Excel檔案也很挑剔,要求這些檔案的尾碼必須是.xls或者.xlsx;否則會報錯。
模組openpyxl源於PHPExcel,它提供了針對.xlsx檔案的讀寫功能。
模組xlsxwriter也需要讀取.xlsx檔案
模組xlrd能用來析取.xls和.xlsx檔案中的資料。下面,我們先來產生用於填充pandas中DataFrame的隨機數,然後用這個DataFrame建立一個Excel檔案,接著再用Excel檔案重建DataFrame,並通過mean()方法來計算其平均值。對於Excel檔案的工作表,我們既可以為其指定一個從0開始計數的索引,也可以為其規定一個名稱
import numpy as npimport pandas as pdfrom tempfile import NamedTemporaryFilenp.random.seed(42)a=np.random.randn(365,4)tmpf=NamedTemporaryFile(suffix=‘.xlsx‘)df=pd.DataFrame(a)print(tmpf.name)df.to_excel(tmpf.name,sheet_name=‘Random Data‘)print("Means\n",pd.read_excel(tmpf.name,‘Random Data‘).mean())
通過to_excel()方法建立Excel檔案,有用頂級read_excel()函數來重建DataFrame
6.使用pandas讀寫JSON
pandas提供的read_json()函數,可以用來建立pandas Series或者pandas DataFrame資料結構。
import pandas as pdjson_str=‘{"country":"Netherlands","dma_code":"0","timezone":"Europe\/Amsterdam","area_code":"0","ip":"46.19.37.108","asn":"AS196752","continent_code":"EU","isp":"Tilaa V.O.F.","longitude":5.75,"latitude":52.5,"country_code":"NL","country_code3":"NLD"}‘data=pd.read_json(json_str,typ=‘series‘)print("Series\n",data)data["country"]="Brazil"print("New Series\n",data.to_json())
調用read_json()函數時,既可以向其傳遞一個JSON字串,也可以為其指定一個JSON檔案的路徑。上面的例子中,我們是利用JSON字串來建立pandas Series
並且再次修改country的值,並用to_json()方法將其從pandas Series轉換為JSON字串
《Python 資料分析》筆記——資料的檢索、加工與儲存