乾貨:手把手教你用Python讀寫CSV、JSON、Excel及解析HTML

導讀:本文要介紹的這些技法,會用Python讀入各種格式的數據,並存入關係數據庫或NoSQL數據庫。

作者:托馬茲·卓巴斯(Tomasz Drabas)

本文摘編自《數據分析實戰》,如需轉載請聯繫我們

乾貨:手把手教你用Python讀寫CSV、JSON、Excel及解析HTML

本文的源代碼與數據集都可在Github上獲取。如果要複製代碼庫,打開你的終端(Windows環境下的命令行、Cygwin或Git Bash,Linux/Mac環境下的Terminal),鍵入下面這條命令:

git clone https://github.com/drabastomek/practicalDataAnalysisCookbook.git

注意,你的機器得裝好Git了。安裝指南參見:

  • https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

我們將使用一個數據集,包含985項真實的房產交易。這些交易是連續5天內在Sacramento發生的。數據下載自:

  • https://support.spatialkey.com/spatialkey-sample-csv-data/

精確地說,來自:

  • http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv

數據已轉成多種格式,放在GitHub代碼庫的Data/Chapter01文件夾中。

另外,你會學到如何從HTML文件中檢索信息。出於這個目的,我們將使用Wikipedia上字母A打頭的機場列表:

  • https://en.wikipedia.org/wiki/List_of_airports_by_IATA_code:_A

我們將使用OpenRefine清理我們的數據集;它很擅長數據的讀取、清理以及轉換數據。

01 用Python讀寫CSV/TSV文件

CSV和TSV是兩種特定的文本格式:前者使用逗號分隔數據,後者使用\t符。這賦予它們可移植性,易於在不同平臺上共享數據。

1. 準備

要實踐這個技法,你要先裝好pandas模塊。這些模塊在Anaconda發行版Python中都有。如果你裝的是這個版本,就省事了。如果不是,那你得安裝pandas並確保正確加載。

可以從

  • http://docs.continuum.io/anaconda/install

下載Anaconda。

如果你裝了Python,沒有pandas,你可以從

  • https://github.com/pydata/pandas/releases/tag/v0.17.1

下載,並按照文檔安裝到你的操作系統中。

  • http://pandas.pydata.org/pandas-docs/stable/install.html

此外沒有要求了。

2. 怎麼做

pandas模塊提供了高性能的高級數據結構(比如DataFrame)以及一些基本的分析工具。

DataFrame是一種數據結構,有點像Excel表格,列代表數據集的維度(例如,人的身高和體重),行存儲著數據(例如,1000個人的具體身高和體重數據)。參考:

  • http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe

這個模塊提供了一些方法,便於讀取各種格式的數據。下面這小塊代碼讀取了CSV和TSV格式的數據,存入pandas DataFrame數據結構,然後寫回到磁盤上(read_csv.py文件):

import pandas as pd

# 讀出數據的文件名

r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

# 寫進數據的文件名

w_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

w_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

# 讀取數據

csv_read = pd.read_csv(r_filenameCSV)

tsv_read = pd.read_csv(r_filenameTSV, sep='\t')

# 輸出頭10行記錄

print(csv_read.head(10))

print(tsv_read.head(10))

# 寫入文件

with open (w_filenameCSV, 'w') as write_csv:

write_csv.write(tsv_read.to_csv(sep=',', index=False))

with open(w_filenameTSV, 'w') as write_tsv:

write_tsv.write(csv_read.to_csv(sep='\t', index=False))

打開命令行控制檯(Windows環境下可使用命令或Cygwin,Linux/Mac環境下可使用Terminal),執行這條命令:

python read_csv.py

你會看到類似這樣的輸出:

| Baths | beds | | city | latitude | longitude | price |

| 0 | 1 | 2 | SACRAMENTO | 38.631913 | -121.434879 | 59222 |

| 1 | 1 | 3 | SACRAMENTO | 38.478902 | -121.431028 | 68212 |

| 2 | 1 | 2 | SACRAMENTO | 38.618305 | -121.443839 | 68880 |

3. 原理

首先加載pandas,以使用DataFrame及相關方法來讀寫數據。注意,關鍵詞as賦給pandas一個別名pd。這樣在後面的代碼中,使用DataFrame或read_csv(...)方法時,我們就不用寫出包的全名了。我們將(用於讀和寫的)文件名分別存於變量r_filenameCSV(TSV)和w_filenameCSV(TSV)。

使用pandas的read_csv(...)方法讀取數據。這個方法用途很廣,接受一系列輸入參數。但有一個參數是必需的,一個文件名或緩衝區,也就是一個打開的文件對象。要解析realEstate_trans.tsv文件,你要指定sep=‘\t’參數;默認情況下,read_csv(...)方法會推斷文件使用的分隔符,不過我可不喜歡碰運氣式編程,向來是指定分隔符的。

兩個文件中的數據一模一樣,所以你可以輸出一些記錄,看看文件是否正確讀入。這可通過對DataFrame對象應用.head()方法達成,其中指的是要輸出的行數。

將數據存於pandas DataFrame對象意味著,數據的原始格式並不重要;一旦讀入,它就能保存成pandas支持的任何格式。在前面這個例子中,我們就將CSV文件中讀取的內容寫入了TSV文件。

無論讀寫,打開文件都要使用with open(…) as …:這個固定搭配。這種方式的優點在於,一旦完成了讀寫任務,即使由於某些原因拋出了異常,文件依然會正確關閉。

異常是指程序員寫代碼時期望之外的情況。

例如,假設你有一個文件,每行只包含一個數字:你打開這個文件,開始讀取。每一行作為文本讀入,你需要將文本轉為一個整數——計算機可以將其作為數字理解(並處理)的數據結構,而非文本。

當數據中只有數字時一切安好。然而,你將會認識到,我們收集的數據在某些方面是有瑕疵的,那麼,某些行包含一個字母而非數字時,文本到整數的轉換會失敗,而Python會拋出一個異常。

open(, ‘w’)會以寫模式(w參數)打開指定的文件。也可以傳入’r’指定以讀模式打開文件。以’r+’模式打開文件允許數據的雙向流動(讀取和寫入),這樣你就可以在需要時往文件的末尾附加內容。你也可以指定rb或wb來處理二進制數據(而非文本)。

to_csv(…)方法將DataFrame的內容轉換為可存儲於文本文件的格式。你要指定分隔符,比如sep=‘,’,以及是否保存DataFrame的索引,默認是保存的。我們不希望存,所以要指定index=False。

用索引可以很方便地辨認、校準、訪問DataFrame中的數據。索引可以是一列連續的數字(就像Excel中的行號)或日期;你還可以設定多列索引。索引列並不是數據(即便打印DataFrame對象時你會在屏幕上看到索引)。

  • http://pandas.pydata.org/pandas-docs/stable/indexing.html

4. 更多

這裡介紹讀寫CSV、TSV文件最方便最快捷的方法。如果你不想把數據存於pandas的DataFrame數據結構,你可以使用csv模塊。像下面這樣讀取文件(read_csv_alternative.py文件):

import csv

# 讀入數據的文件名

r_filenameCSV = '../../Data/Chapter01/realEstate_trans.csv'

r_filenameTSV = '../../Data/Chapter01/realEstate_trans.tsv'

# 保存數據的數據結構

csv_labels = []

tsv_labels = []

csv_data = []

tsv_data = []

# 讀取數據

with open(r_filenameCSV, 'r') as csv_in:

csv_reader = csv.reader(csv_in)

# 讀取第一行,這是列標籤

csv_labels = csv_reader.__next__()

# 遍歷記錄

for record in csv_reader:

csv_data.append(record)

with open(r_filenameTSV, 'r') as tsv_in:

tsv_reader = cvs.reader(tsv_in, delimiter='\t')

tsv_labels = tsv_reader.__next__()

for record in tsv_reader:

tsv_data.append(record)

# 打印標籤

print(csv_labels, '\n')

print(tsv_labels, '\n')

# 打印頭10行記錄

print(csv_data[0:10], '\n')

print(tsv_data[0:10], '\n')

我們將標籤和數據分別存儲於csv(tsv)_labels和csv(tsv)_data兩個列表。.reader(…)方法從文件中逐行讀取數據。要創建.reader(…)對象,你要傳入一個打開的CSV或TSV文件對象。另外,要讀入TSV文件,你也得像DataFrame中一樣指定分隔符。

csv模塊也提供了csv.writer對象,可將數據以CSV/TSV格式存儲。參見csv模塊的文檔:

  • https://docs.python.org/3/library/csv.html

5. 參考

查閱pandas文檔中講解reader_csv(…)和write_csv(…)的部分,瞭解更多可傳入的參數。文檔位於:

  • http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table

02 用Python讀寫JSON文件

JSON的全稱是JavaScript Object Notation。這是個嵌套的、類似字典的結構,以逗號為分隔符,存儲鍵值對;鍵與值之間以冒號分隔。JSON格式獨立於具體平臺(就像XML,我們將在 用Python讀寫XML文件介紹),便於平臺之間共享數據。

要深入瞭解JSON,可參考:

  • http://www.w3schools.com/json/

1. 準備

要實踐這個技法,你要先裝好pandas模塊。此外沒有要求了。

2. 怎麼做

下面是讀取JSON文件的代碼。注意,我們假設已經引入了pandas模塊,並以別名pd指代(read_json.py文件):

# 讀出數據的JSON文件

r_filenameJSON = '../../Data/Chapter01/realEstate_trans.json'

# 讀取數據

json_read = pd.read_json(r_filenameJSON)

# 打印頭10行記錄

print(json_read.head(10))

3. 原理

這段代碼與前一節的類似。首先,指定JSON文件的名字——我們將其存於r_filenameJSON字符串中。然後,使用pandas的read_json(…)方法,傳入r_filenameJSON。

讀出的數據存儲於json_read這一DataFrame對象。進而使用.tail(…)方法打印出最後10條數據。要寫入一個JSON文件,你可以對DataFrame使用.to_json()方法,將返回的數據寫進一個文件,類似用Python讀寫CSV/TSV文件中介紹的流程。

4. 更多

也可以使用json模塊來讀寫JSON文件。可以使用下面的代碼從JSON文件中讀取數據(read_json_alternative.py文件):

# 讀取數據

with open('../../Data/Chapter01/realEstate_trans.json', 'r') as json_file:

jsonread = json.loads(json_file.read())

這段代碼將realEstate_trans.json文件中讀出的數據存入json_read列表。這裡對文件使用了.read()方法,將文件內容全部讀入內存。下面的代碼將數據存儲於一個JSON文件:

# 寫回到文件中

with open('../../Data/Chapter01/realEstate_trans.json', 'w') as json_file:

json_file.write(json.dumps(json_read))

5. 參考

參閱pandas文檔中read_json的部分。文檔位於:

  • http://pandas.pydata.org/pandas-docs/stable/io.html#io-json-reader

03 用Python讀寫Excel文件

以表格形式操作數據的文件格式中,Microsoft的Excel文件可以說是最流行的了。拿最新的XLSX格式來說,Excel可以在單個工作表中存儲一百多萬行及一萬六千多列。

1. 準備

要實踐這個技法,你要先裝好pandas模塊。此外沒有要求了。

2. 怎麼做

下面是讀取JSON文件的代碼。注意,我們假設已經引入pandas模塊,並以pd指代(read_xlsx.py文件):

# 讀寫數據的文件名

r_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

w_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

# 打開Excel文件

xlsx_file = pd.ExcelFile(r_filenameXLSX)

# 讀取內容

xlsx_read = {

sheetName: xlsx_file.parse(sheetName) for sheetName in xlsx_file.sheet_names

}

# 打印Sacramento頭10份價格

print (xlsx_read['Sacramento'].head(10)['price'])

# 寫入Excel文件

xlsx_read['Sacramento'].to_excel (w_filenameXLSX, 'Sacramento', index=False)

3. 原理

類似之前的例子。用pandas的ExcelFile(...)方法打開XLSX文件,並賦給xlsx_file對象。用.parse(...)方法讀取指定工作表的內容,並存儲於xlsx_read字典。注意,通過ExcelFile對象的.sheet_names屬性,你可以訪問Excel文件中的所有工作表。

創建xlsx_read字典時,我們使用了字典表達式,這個做法很Python:不是顯式地遍歷工作表,將元素添加到字典,而是使用字典表達式,讓代碼更可讀、更緊湊。

表達式效仿數學上的表示方法,這讓代碼更容易理解。比方說,2的冪次的列表:(A = (2^0, 2^1, 2^2, …, 2^8) = (2^x: 0 <= x < 9), x取整數)。使用表達式很容易轉成Python代碼:A = [2**x for x in range(0, 9)]。就創建了這樣的列表:A = [1, 2, 4, 8, 16, 32, 64, 128, 256]。

另外,Python裡,表達式也比顯式的循環要快那麼一點點。

  • http://stackoverflow.com/questions/22108488/are-list-comprehensions-and-functional-functions-faster-than-for-loops

range(, )函數生成了從-1的一列整數。例如,range(0, 3)生成的序列是0,1,2.

存儲數據到Excel文件中也很簡單。僅需調用.to_excel(...)方法,第一個參數傳你要保存數據的文件名,第二個參數傳工作表的名字。在我們的例子中,我們還指定了index=False,這樣不會保存索引;默認情況下,.to_excel(...)方法保存A列的索引。

4. 更多

讀取Excel文件,除了用pandas的read_excel(...)方法,你也可以選擇其它Python模塊。pandas使用xlrd讀取數據並轉成DataFrame。

  • https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966

對於XLSX文件,你也可以使用openpyxl模塊(read_xlsx_alternative.py文件):

import openpyxl as oxl

# 讀出數據的文件名

r_filenameXLSX = '../../Data?Chapter01/realEstate_trans.xlsx'

# 打開Excel文件

xlsx_wb = oxl.load_workbook(filename=r_filenameXLSX)

# 工作簿中所有工作表的名字

sheets = xlsx_wb.get_sheet_names()

# 提取'Sacramento'工作表

xlsx_ws = xlsx_wb[sheets[0]]

首先,讀取Excel文件,存入xlsx_wb(工作簿)。從工作簿中提取所有工作表的名字,並存入sheets變量。這裡我們的工作簿中只有一個工作表,所以sheets變量就等於'Sacramento'。我們用它創建一個xlsx_ws對象,以遍歷所有的行:

labels = [cell.value for cell in xlsx_ws.rows[0]]

data = [] # 保存數據的列表

for row in xlsx_ws.rows[1:]:

data.append([cell.value for cell row])

第一行是所有列的標籤,最好還是單獨存儲——我們放到labels變量中。進而使用.rows迭代器,遍歷工作表中每一行,將所有單元格中的數據加入data列表:

print (

[item[labels.index('price')] for item in data[0:10]]

)

代碼最後打印出頭10行的房屋價格。我們使用表達式生成價格的列表。如代碼所示,對於列表對象,你可以調用.index(...)方法查找某一元素首次出現的位置。

5. 參考

  • 查閱pandas文檔中read_excel的部分。文檔在

http://pandas.pydata.org/pandas-docs/stable/io.html#io-excel

另外,你可以訪問

  • http://www.python-excel.org

找到一系列模塊,可幫你處理.xls和.xlsx等Excel文件格式。

乾貨:手把手教你用Python讀寫CSV、JSON、Excel及解析HTML

04 用Python讀寫XML文件

XML的全稱是eXtensible Markup Language(擴展標記語言)。儘管不像前面介紹的格式那樣流行,不少網絡API還是支持XML編碼的。

XML文檔結構類似一棵樹。讀取內容時,我們首先訪問根節點(通常來說,這個節點後面會跟著XML的聲明;每個XML文檔都要以這樣的聲明開頭)。在我們的例子中,根節點是。一個...中包含了一系列...

當心:xml模塊不安全。處理未知來源的XML消息時必須得小心。攻擊者可能訪問本地文件,發動DoS攻擊等等。

xml模塊的文檔參見:

  • https://docs.python.org/3/library/xml.html

1. 準備

要實踐這個技法,你要先裝好pandas和xml模塊。此外沒有要求了。

2. 怎麼做

從XML文件直接向一個pandas DataFrame對象讀入數據需要些額外的代碼:這是由於XML文件有特殊的結構,需要針對性地解析。接下來的章節,我們會詳細解釋這些方法。源代碼可在read_xml.py文件中找到:

import pandas as pd

import xml.etree.ElementTree as ET

def read_xml(xml_tree):

'''

讀入XML數據,返回pd.DataFrame

'''

def iter_records(records):

'''

遍歷所有記錄的生成器

'''

def write_xml(xmlFileName, data):

'''

以XML格式保存數據

'''

def xml_encode(row):

'''

以特定的嵌套格式將每一行編碼成XML

'''

# 讀出和寫入數據的文件名

r_filenameXML = '../../Data/Chapter01/realEstate_trans.xml'

w_filenameXML = '../../Data/Chapter01/realEstate_trans.xml'

# 讀取數據

xml_read = read_xml (r_filenameXML)

# 打印頭10行記錄

print (xml_read.head(10))

# 以XML格式寫回到文件

write_xml(w_filenameXML, xml_read)

3. 原理

我們一步步分析前面的代碼。首先引用需要的模塊。xml.etree.ElementTree是一個輕量級XML解析器,我們用它來解析文件的XML結構。和之前一樣,分別將讀取和寫入的文件名定義為變量(r_filenameXML,w_filenameXML)。

使用read_xml(...)方法從XML文件讀取數據:

def read_xml(xmlFileName):

with open(xmlFileName, 'r') as xml_file:

# 讀取數據,以樹的結構存儲

tree = ET.parse(xml_file)

# 訪問樹的根節點

root = tree.getroot()

# 返回DataFrame

return pd.DataFrame(list(iter_records(root)))

這個方法只消傳入文件名這一個參數。首先,打開文件。使用.parse(...)方法,我們由XML文件創建了一個樹狀結構並存入tree對象。接著,在tree對象上用.getroot()方法提取根節點:這是進一步處理數據的前提。最後一行調用iter_records方法,傳入根節點的引用,進而將返回的信息轉換成DataFrame:

def iter_records(records):

for record in records:

# 保存值的臨時字典

temp_dict = {}

# 遍歷所有字段

for var in record:

temp_dict[

var.attrib['var_name']

] = var.text

# 生成值

yield temp_dict

iter_records方法是一個生成器:顧名思義,這個方法生成一些值。普通方法結束時(return語句)一次性返回所有的值;生成器不同,每次只向調用方返回一個值(即yield關鍵字),直到結束。

更深入地討論生成器,建議閱讀

  • https://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/

我們的iter_records方法,每讀入一行,就返回一個temp_dict字典對象給read_xml方法。字典中每個元素的鍵名對應XML中元素的var_name屬性。(有這樣的格式:。)

標籤可能有其它名字的屬性——這些屬性會存在.attrib字典(XML樹節點一個屬性)並通過各自的名字訪問——參考代碼中高亮的部分。

的值(...內的部分)可通過XML節點的.text屬性訪問,而.tag屬性存儲其名字(這個例子中就是var)。

read_xml方法的return語句從傳入的所有字典中創建一個列表,轉換成DataFrame。

我們使用write_xml(...)方法,以XML格式寫入數據:

def write_xml (xmlFileName, data):

with open (xmlFileName, 'w') as xmlFile:

# 寫頭部

xmlFile.write(

'\n'

)

xmlFile.write('\n')

# 寫數據

xmlFile.write(

'\n'.join(data.apply(xml_encode, axis=1))

)

# 寫尾部

xmlFile.write('\n')

這個方法打開xmlFileName參數指定的文件。每個XML文件需要以XML聲明開頭(參考本技法的導論)。接著,我們寫了XML schema的根節點,

接下來就是寫數據。使用DataFrame對象的.apply(...)方法遍歷內部每一行。第一個參數指定了要應用到每行記錄上的方法。axis參數的默認值為0。意味著指定的方法會應用到DataFrame的每一列上。指定為1,我們讓.applay(...)方法將指定的xml_encode(...)方法應用到DataFrame的每一行上。使用xml_encode(...)方法處理data DataFrame的每一行:

def xml_encode(row):

# 第一步——輸出record節點

xmlItem = ['']

# 第二步——給行中每個字段加上XML格式

for field in row.index:

xmlItem \

.append(

' {1}' \

.format (file, row[field])

)

# 最後一步——標記record節點的結束標籤

xmlItem.append('')

# 返回一個字符串

return '\n'.join(xmlItem)

代碼生成了一個字符串列表,xmlItem。列表的首元素是,尾元素是。對行中每個字段,我們以>的格式封裝,並加進字符串列表。加粗部分指的是列名()和對應的值(

)。

解析完所有字段後,使用'\n'.join(...)方法,將xmlItem列表中所有項連接成一個長字符串。...標籤之間以\n分隔。這個字符串被返回給調用方(write_xml)。記錄在write_xml(...)方法中進一步連接,並輸出到文件。最後加上閉合標籤,大功告成。

05 用pandas解析HTML頁面

儘管以前面介紹的格式保存數據是最常見的,我們有時還是要在網頁表格中查找數據。數據的結構通常包含在

標籤內。本技法會介紹如何從網頁獲取數據。

1. 準備

要實踐這個技巧,你要先裝好pandas和re模塊。re是Python的正則表達式模塊,我們用它來清理列名。另外,使用pandas 的read_html(...)方法要預裝html5lib模塊。如果你使用的是Anaconda發行版Python,使用下面的命令就可以:

conda install html5lib

如果不是,你可以從

  • https://github.com/html5lib/html5lib-python

下載源代碼。解壓,手動安裝模塊:

cd html5lib-python-parserpython setup.py install

此外沒有要求了。

2. 怎麼做

pandas可以很方便地訪問、提取、解析HTML文件。兩行代碼就能搞定。retrieve_html.py可不止兩行,這些我們下一環節再討論:

# 要調用的url

url = 'https://en.wikipedia.org/wiki/' + \

'List_of_airports_by_IATA_code:_A'

# 從HTML提取數據

url_read = pd.read_html (url, header = 0)[0]

3. 原理

pandas 的read_html(...)方法解析HTML文件的DOM結構,從所有table節點中提取數據。第一個參數可以是URL、文件或HTML標籤原始字符串。第二個參數指定header = 0,忽略了表頭。

read_html(...)方法返回了一個DataFrame對象的列表,每項對應於HTML文件中一個table。Wikipedia的機場頁面只包含了一個table,所以我們只要取DataFrame列表的首元素。是的,就是這樣!機場列表已經在url_read對象中了。

拿到的數據還有兩點瑕疵:列名包含空白字符,數據包含分隔行。對於名字中可能包含多種空白字符(空格符、製表符等)的問題,我們使用re模塊:

import re

# 匹配字符串中任意空白字符的正則表達式

space = re.compiler(r'\s+')

def fix_string_spaces (columnsToFix):

'''

將列名中的空白字符換成下劃線

'''

tempColumnNames = [] # 保存處理後的列名

# 循環處理所有列

for item in columnsToFix:

# 匹配到

if space.search (item):

# 處理並加入列表

tempColumnNames \

.append('_'.join (space.split (item)))

else:

# 否則直接加入列表

tempColumnNames.append (item)

return tempColumnNames

首先,編譯那個匹配出至少一個空白字符的正則表達式。

對正則表達式的詳細討論超出了本書的知識範圍。關於這個主題,有個知識手冊寫得挺好的:

  • https://www.packtpub.com/application-development/mastering-python-regular-expressions

或者參考re模塊的文檔:

  • https://docs.python.org/3/library/re.html

然後循環處理列,找到空白字符(space.search(...))時,將列名拆開(space.split(...))存入列表。以’_’為間隔,連接列表元素。如果不含空白字符,就將原始列名加入列表。使用下面這行代碼處理DataFrame中的列名:

url_read.columns = fix_string_spaces (url_read.columns)

查看Wikipedia上的機場表,你會發現它根據前兩個字母分組,組與組之間有分隔行。分隔行中缺失了其它列。為了處理這個問題,我們使用DataFrame的.dropna (...)方法。

pandas有多種方法用於處理NaN(Not a Number)情況。估算缺失值會介紹.fillna (...)方法。

.dropna (...)方法刪掉缺少任意字段數據的行(或者列)。調用.dropna (...)時很容易不傳任何參數,這樣即便是合理的行,只要缺了夏時制(Daylight Saving Time, DST)或國際民航組織機場代碼,也會被刪掉。我們可以設道門檻。

粗粗瀏覽下數據可以發現,有些合理的行最多會缺兩個字段。參數inplace=True直接在原來的DataFrame對象上移除數據,而非複製出一個DataFrame、清理後再返回;默認值是inplace=False:

url_read.dropna (thresh=2, inplace=True)

移除一些行後,DataFrame的索引會產生空洞。可以使用這行代碼:

url_read.index = range (0, len(url_read))

下面這行代碼輸出頭10行IATA代碼及對應的機場名:

print (url_read.head (10)[['IATA', 'Airport_name']])

如果想取出不止一列,可以以列表的形式傳入;在我們的例子中,就是['IATA', 'Airport_name']。下面的代碼是等效的:

print (url_read[0:10] [['IATA', 'Airport_name']])

關於作者:托馬茲·卓巴斯(Tomasz Drabas)微軟數據科學家,致力於解決高維特徵空間的問題。他有超過13年的數據分析和數據科學經驗:在歐洲、澳大利亞和北美洲三大洲期間,工作領域遍及高新技術、航空、電信、金融和諮詢。

本文摘編自《數據分析實戰》,經出版方授權發佈。

乾貨:手把手教你用Python讀寫CSV、JSON、Excel及解析HTML

延伸閱讀《數據分析實戰》

推薦語:通過大量的現實案例,詳細講解數據分析相關的各種方法。


分享到:


相關文章: