Python數據分析之Pandas讀寫外部數據文件


1 引言

數據分析、數據挖掘、可視化是Python的眾多強項之一,但無論是這幾項中的哪一項都必須以數據作為基礎,數據通常都存儲在外部文件中,例如txt、csv、excel、數據庫。本篇中,我們來捋一捋Python中那些外部數據文件讀取、寫入的常用方法。

下表是Pandas官方手冊上給出的一張表格,表格描述的是Pandas中對各種數據文件類型的讀、寫函數,你可以直接在官方手冊中找到:

通過閱讀表格,可以發現,Pandas中提供了非常豐富的數據讀寫方法。不過本文只講述文本文件(txt、csv)、excel文件、關系型數據庫(mysql)、非關系型數據庫(mongodb)的讀寫方式。

2 文本文件(txt、csv)

無論是txt文件還是csv文件,在Pandas中都使用read_csv()方法讀取,當然也使用同一個方法寫入到文件,那就是to_csv()方法。

我們先來說說怎么讀取數據。所要讀取的文件名為“data.csv",文件內容用記事本打開后如下所示:

2.1 讀取數據

為了提供更加多樣化、可定制的功能,read_csv()方法定義了參數數十個參數,還好的是大部分參數並不常用,而且絕大多數情況使用默認值就可以,所以只需要記住以下的幾個比較常用的參數就可以了:

(1)filepath_or_buffer:文件所在路徑,可以是一個描述路徑的字符串、pathlib.Path對象、http或ftp的連接,也可以是任何可調用read()方法的對象。這個參數是唯一一個必傳的參數。

>>> import pandas as pd
>>> df = pd.read_csv('data.csv', encoding='gbk')
>>> df
姓名 語文 數學 英語
0 陳一 89 90 67
1 趙二 70 78 90
2 張三 87 86 79
3 李四 90 69 84
4 王五 78 80 69

(2)encoding :編碼,字符型,通常為'utf-8',如果中文讀取不正常,可以將encoding設為’gbk‘。

在上面打開data.csv文件的例子中,如果不指定encoding='gbk'則會出現下面的異常。當然,你也可以在記事本中通過另存為的方式將編碼修改為utf-8,這樣就可以使用默認的utf-8編碼。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0: invalid continuation byte

(3)sep:分隔符,默認為一個英文逗號,即','。

(4)delimiter :備選分隔符,如果指定了delimiter則sep失效。

(5)header :整數或者由整數組成的列表,以用來指定由哪一列或者哪幾列作為列名,默認為header=0,表示第一列作為列名。

>>> pd.read_csv('data.csv', encoding='gbk', header=1) # 指定第二列作為列名
陳一 89 90 67
0 趙二 70 78 90
1 張三 87 86 79
2 李四 90 69 84
3 王五 78 80 69

可以看到,當指定第一行之后的數據作為列名時,前面的所有行都會被略過。

也可以傳遞一個包含多個整數的列表給header,這樣每一列就會有多個列名。如果中間某一行沒有指定,那么改行會被略過,例如下面的第三行:

>>> df = pd.read_csv('data.csv', encoding='gbk', header=[0,1,3])
>>> df
姓名 語文 數學 英語
陳一 89 90 67
張三 87 86 79
0 李四 90 69 84
1 王五 78 80 69

當文件中沒有列名一行數據時,可以傳遞header=None,表示不從文件數據中指定行作為列名,這是Pandas會自動生成從零開始的序列作為列名:

>>> df = pd.read_csv('data.csv', encoding='gbk', header=None)
>>> df
0 1 2 3
0 姓名 語文 數學 英語
1 陳一 89 90 67
2 趙二 70 78 90
3 張三 87 86 79
4 李四 90 69 84
5 王五 78 80 69

(6)names:一個列表,為數據額外指定列名。

>>> df = pd.read_csv('data.csv', encoding='gbk', names=['第一列', '第二列', '第三列', '第四列'])
>>> df
第一列 第二列 第三列 第四列
0 姓名 語文 數學 英語
1 陳一 89 90 67
2 趙二 70 78 90
3 張三 87 86 79
4 李四 90 69 84
5 王五 78 80 69

2.2 寫入數據

to_csv()方法可以將Pandas數據寫入到文本文件中,常用參數如下:

(1)path_or_buf:表示路徑的字符串或者文件句柄。例如,將上面讀取出來的數據寫入到名為data_1.txt文件中:

df.to_csv('data_1.txt')

如果data_1.txt文件不存在,則會新建data_1.txt文件后再寫入,如果本來已存在該文件,則會清空后再寫入,寫入后data_1.txt文件內容如下:

,第一列,第二列,第三列,第四列

0,姓名,語文,數學,英語

1,陳一,89,90,67

2,趙二,70,78,90

3,張三,87,86,79

4,李四,90,69,84

5,王五,78,80,69

可以看到,無論是行索引還是列名和真實數據都寫入到了文件中。

(2)sep:分隔符,默認為因為逗號’,‘。例如指定分隔符為’-‘將之前讀取的數據寫入文件中:

>>> df.to_csv('data_1.txt', sep='*')

寫入后data_1.txt文件內容如下:

*第一列*第二列*第三列*第四列
0*姓名*語文*數學*英語
1*陳一*89*90*67
2*趙二*70*78*90
3*張三*87*86*79
4*李四*90*69*84
5*王五*78*80*69

(3)header:元素為字符串的列表,或布爾型數據。當為列表時表示重新指定列名,當為布爾型時,表示是否寫入列名:

df.to_csv('data_1.txt', header=['第1列', '第2列', '第3列', '第4列'])

寫入數據后文件內容:

,第1列,第2列,第3列,第4列
0,姓名,語文,數學,英語
1,陳一,89,90,67
2,趙二,70,78,90
3,張三,87,86,79
4,李四,90,69,84
5,王五,78,80,69

(4)columns:一個列表,重新指定寫入文件中列的順序。

df.to_csv('data_1.txt', columns=['第四列', '第二列', '第三列', '第一列'])

寫入后文件內容:

,第四列,第二列,第三列,第一列
0,英語,語文,數學,姓名
1,67,89,90,陳一
2,90,70,78,趙二
3,79,87,86,張三
4,84,90,69,李四
5,69,78,80,王五

(5)index_label :字符串或布爾型變量,設置索引列列名:

>>> df.to_csv('data_1.txt', index_label='index')

寫入后文件內容:

index,第一列,第二列,第三列,第四列

0,姓名,語文,數學,英語

1,陳一,89,90,67

2,趙二,70,78,90

3,張三,87,86,79

4,李四,90,69,84

5,王五,78,80,69

>>> df.to_csv('data_1.txt', index_label=False)

第一列,第二列,第三列,第四列

0,姓名,語文,數學,英語

1,陳一,89,90,67

2,趙二,70,78,90

3,張三,87,86,79

4,李四,90,69,84

5,王五,78,80,69

(6)index:布爾型,是否寫入索引列,默認為True

>>> df.to_csv('data_1.txt', index=False, index_label=False)

第一列,第二列,第三列,第四列

姓名,語文,數學,英語

陳一,89,90,67

趙二,70,78,90

張三,87,86,79

李四,90,69,84

王五,78,80,69

(7)encoding:寫入的編碼,默認是utf-8。

>>> df.to_csv('data_1.csv', encoding='gbk')

寫入后文件內容:

,第一列,第二列,第三列,第四列

0,姓名,語文,數學,英語

1,陳一,89,90,67

2,趙二,70,78,90

3,張三,87,86,79

4,李四,90,69,84

5,王五,78,80,69

3 excel文件

在使用pandas讀取excel文件之前,需要先安裝Python讀取excel的依賴包:xlrd,可以使用pip命令從豆瓣源上下載:

pip install -i https://pypi.douban.com/simple xlrd

示例文件名為data.xlsl,里面有兩張sheet,sheet1內容如下:

Sheet2內容如下:

3.1 讀取數據

pandas讀取excel數據通過reade_excel方法,下面通過實例來感受一下read_excel方法的幾個常用參數:

(1)io:需要讀取的文件,可以是文件路徑、文件網址、file-like對象、xlrd workbook對象。這是唯一一個必填的參數。

>>> pd.read_excel('data.xlsx')
姓名 語文 數學 英語
0 陳一 89 90 67
1 趙二 70 78 90
2 張三 87 86 79
3 李四 90 69 84
4 王五 78 80 69

(2)sheet_name :指定需要讀取的Sheet。有一下幾種情況:

  • 整型:通過數字索引讀取Sheet,索引從0開始,sheet_name默認參數就是0,表示讀取第一張Sheet。

>>> pd.read_excel('data.xlsx', sheet_name=1)
姓名 語文 數學 英語
0 李白 70 80 90
1 杜浦 70 80 90
2 王安石 70 80 90
3 蘇東坡 70 80 90
4 李清照 70 80 90
  • 字符型:通過名稱來讀取Sheet。

>>> pd.read_excel('data.xlsx', sheet_name='Sheet2')
姓名 語文 數學 英語
0 李白 70 80 90
1 杜浦 70 80 90
2 王安石 70 80 90
3 蘇東坡 70 80 90
4 李清照 70 80 90
  • 列表:指定多個需要讀取的Sheet,列表的元素可以使索引,也可以是字符串,例如[0, 1, 'Sheet3']表示讀取第一張、第二張和名為Sheet3的3張Sheet,返回的數據是以列表元素為鍵包含數據的DataFrame對象為值的字典。
>>> data = pd.read_excel('data.xlsx', sheet_name=[0, 'Sheet2'])
>>> data[0]
姓名 語文 數學 英語
0 陳一 89 90 67
1 趙二 70 78 90
2 張三 87 86 79
3 李四 90 69 84
4 王五 78 80 69
>>> data['Sheet2']
姓名 語文 數學 英語
0 李白 70 80 90
1 杜浦 70 80 90
2 王安石 70 80 90
3 蘇東坡 70 80 90
4 李清照 70 80 90
  • None:表示讀取所有Sheet,返回的是以Sheet名為鍵,包含數據的DataFrame對象為值的字典。
>>> data = pd.read_excel('data.xlsx', sheet_name=None)
>>> data['Sheet1']
姓名 語文 數學 英語
0 陳一 89 90 67
1 趙二 70 78 90
2 張三 87 86 79
3 李四 90 69 84
4 王五 78 80 69
>>> data['Sheet2']
姓名 語文 數學 英語
0 李白 70 80 90
1 杜浦 70 80 90
2 王安石 70 80 90
3 蘇東坡 70 80 90
4 李清照 70 80 90

(3)header:指定Sheet的表頭,參數可以表示行索引是整型,表示指定哪一行作為表頭,默認值是0,表示以第一行作為表頭。也可以是元素為整型的列表,表示選用多行作為表頭。

>>> pd.read_excel('data.xlsx', sheet_name='Sheet2', header=1) # 整型指定一行作為表頭
李白 70 80 90
0 杜浦 70 80 90
1 王安石 70 80 90
2 蘇東坡 70 80 90
3 李清照 70 80 90
>>> pd.read_excel('data.xlsx', sheet_name='Sheet2', header=[0,2]) # 列表指定多行作為表頭
姓名 語文 數學 英語
杜浦 70 80 90
0 王安石 70 80 90
1 蘇東坡 70 80 90
2 李清照 70 80 90

(4)index_col :指定行標簽,或者說行名。當時一個整數時,表示指定某一行行作為行標簽,當是一個列表(元素都為整型)時,表示指定多列作為行標簽。默認值為None,表示自動生成以0開始的整數作為行標簽。

>>> pd.read_excel('data.xlsx', sheet_name=0, index_col=0) # 指定第一行作為行標簽
語文 數學 英語
姓名
陳一 89 90 67
趙二 70 78 90
張三 87 86 79
李四 90 69 84
王五 78 80 69
>>> pd.read_excel('data.xlsx', sheet_name=0, index_col=[0, 1]) # 指定第一行第二行作為行標簽
數學 英語
姓名 語文
陳一 89 90 67
趙二 70 78 90
張三 87 86 79
李四 90 69 84
王五 78 80 69

(5)usecols:指定需要加載的列,參數有以下幾種情況:

  • 默認值None:表示加載所有列

  • 單個整數:加載指定一列,但這種方式未來會被取消,加載單行也最好放在列表里。

>>> pd.read_excel('data.xlsx', sheet_name=0, usecols=1)
姓名 語文
0 陳一 89
1 趙二 70
2 張三 87
3 李四 90
4 王五 78
  • 元素為整數的列表:加載指定多列。
>>> pd.read_excel('data.xlsx', sheet_name=0, usecols=[0,2,3])
姓名 數學 英語
0 陳一 90 67
1 趙二 78 90
2 張三 86 79
3 李四 69 84
4 王五 80 69

3.2 寫入數據

將數據寫入excel得通過DataFrame對象內定義的to_excel()方法。在使用to_excel()方法前,也有一個第三方庫需要裝,那就是openpyxl:

pip install -i https://pypi.douban.com/simple openpyxl

to_excel()方法常用參數如下:

(1)excel_writer:必傳參數,指定需要寫入的excel文件,可以使表示路徑的字符串或者ExcelWriter類對象。

(2)sheet_name:指定需要將數據寫入到哪一張工作表,默認值是Sheet1

(3)float_format:指定浮點型數的格式,例如當指定float_format="%%.2f"時,0.1234將會轉為0.12。

(4)na_rep:字符型,寫入數據時用什么代替空值。

>>> import pandas as pd
>>> pd.read_excel('data.xlsx')
姓名 語文 數學 英語
0 陳一 89.0 90.0 67.0
1 趙二 NaN 78.0 90.0
2 張三 87.0 NaN 79.0
3 李四 90.0 69.0 NaN
4 王五 78.0 80.0 69.0
>>> df = pd.read_excel('data.xlsx')
>>> df.to_excel('data_1.xlsx', na_rep='--')

寫入后文件內容如下所圖示:

(5)header:是否寫入表頭,值可以使布爾型或者元素為字符串的列表,默認為True表示寫入表頭。

>>> df.to_excel('data_1.xlsx', header=['第一列', '第二列', '第三列', '第四列'])

寫入文件內容如下:

(6)index:是否寫入行號,值為布爾型,默認為True,當為False時上面圖中第一列的行號就不會寫入了。

(7)columns:指定需要寫入文件的列,值是元素為整型或字符串的列表。

4 mysql數據庫

在名為test的數據庫中有一張student的表,表結構和數據如下所示:

現在通過pandas來讀取student表數據。在讀取數據之前,先要安裝Python讀取mysql的第三方庫:

pip install -i https://pypi.douban.com/simple pymysql

pandas讀取mysql數據庫時通過pandas中的read_mysql()方法,主要參數如下:

(1)sql:要執行的查詢SQL語句,必傳參數。

(2)conn:數據庫連接,可以使用pymysql創建,必傳參數。

import pandas as pd
import pymysql
 
conn = pymysql.connect(host="localhost",user='chb', password='123456', db="test",charset="utf8")
sql = 'select * from student'
df = pd.read_sql(sql, conn)
print(df)
conn.close()

輸出結果如下:

id name Chinese Math English

0 1 陳一 67 60 56

1 2 李紅 89 87 67

2 3 張大 76 56 98

3 4 杜軍 95 90 72

5 mongodb數據庫

pandas中並沒有直接讀取mongodb數據庫的方法提供,這是讓我很疑惑的地方,畢竟mongodb也是主流的非關系型數據庫。在開始之前,請安裝好pymongo第三方:

pip install -i https://pypi.douban.com/simple pymongo

既然pandas中沒有直接讀取mongodb數據庫的方法,我們就需要用將數據用pymongo讀取出來:

import pandas as pd
import pymongo
client = pymongo.MongoClient(host='localhost', port=27017)
db = client['eleme']
db.authenticate('chb', '123456', 'admin')
collection = db['test']
data = collection.find()
for item in data:
print(item)

輸出結果如下:

{'_id': 1, 'name': '張三', 'Chinese': 67, 'Math': 89, 'English': 97}

{'_id': 2, 'name': '李四', 'Chinese': 65, 'Math': 49, 'English': 78}

{'_id': 3, 'name': '王五', 'Chinese': 81, 'Math': 63, 'English': 84}

{'_id': 4, 'name': '黃六', 'Chinese': 70, 'Math': 69, 'English': 73}

將上面的數據傳遞給pandas,實例化DataFrame對象即可:

import pandas as pd
import pymongo
client = pymongo.MongoClient(host='94.191.85.11', port=27017)
db = client['eleme']
db.authenticate('chb', 'psd.mo.1123', 'admin')
collection = db['test']
data = collection.find()
df = pd.DataFrame(list(data)) # 用讀取出來的數據實例化DataFrame
print(df)

輸出結果如下:

_id name Chinese Math English

0 1 張三 67 89 97

1 2 李四 65 49 78

2 3 王五 81 63 84

3 4 黃六 70 69 73

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM