pandas 文件讀取和分塊讀取


一、文件讀取

在Pandas的使用場景中,最多的是將表格型的數據讀取為DataFrame對象。實現這一功能的函數有很多,最常用的是read_csvread_table

下表列出了pandas主要的讀寫函數:

函數 說明
d_csv 讀取默認以逗號作為分隔符的文件
read_table 讀取默認以制表符分隔的文件
read_fwf 從特定寬度格式的文件中讀取數據(無分隔符)
read_clipboard read_table的剪貼板版本
read_excel 從EXCEL的XLS或者XLSX文件中讀取數據
read_hdf 讀取用pandas存儲的HDF5文件
read_html 從HTML文件中讀取所有表格數據
read_json 從JSON字符串中讀取數據
read_msgpack 讀取MessagePack格式存儲的任意對象
read_pickle 讀取以Python Pickle格式存儲的對象
read_sas 讀取SAS系統中定制存儲格式的數據集
read_sql 將SQL查詢的結果讀取出來
read_stata 讀取stata格式的數據集
read_feather 讀取Feather二進制格式

Pandas不但有這么多的讀取函數,每個函數還有大量的可設置參數。比如read_csv到目前就有超過50個參數。這些函數和參數是如此的復雜,很難有人能夠將它們全部記住,所以當你在讀取文件時遇到了困難,請前往官方文檔,那里的一些示例可能對你有幫助。

讓我們來看看一些具體的例子,首先有這么一個文件:

# ex1.csv
 a,b,c,d,message 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo

可以使用read_csv方法讀取它,默認第一行為列索引,自動生成了行索引:

In [14]: df = pd.read_csv('d:/ex1.csv') In [15]: df Out[15]: a b c d message 0 1   2   3   4 hello 1  5   6   7   8 world 2  9  10  11  12     foo

也可以使用read_table函數,並指定分隔符為逗號:

In [17]: pd.read_table('d:/ex1.csv',sep=',') Out[17]: a b c d message 0 1   2   3   4 hello 1  5   6   7   8 world 2  9  10  11  12     foo

對於不包含表頭行的文件,比如下面的ex2,要么使用默認列名,要么我們指定列名:

1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo

注意指定列名用的參數名是names,不是columns:

In [18]: pd.read_csv('d:/ex2.csv',header=None) # 使用默認列名
Out[18]: 0 1   2   3      4 0 1   2   3   4 hello 1  5   6   7   8 world 2  9  10  11  12 foo In [19]: pd.read_csv('d:/ex2.csv', names=['a','b','c','d','message']) # 自定義
Out[19]: a b c d message 0 1   2   3   4 hello 1  5   6   7   8 world 2  9  10  11  12     foo

如果你想將上面的message列當作DataFrame的行索引,可以將它傳遞給參數index_col:

# 注意其中的names依然必須包含message字符串,否則會彈出KeyError
In [20]: pd.read_csv('d:/ex2.csv', names=['a','b','c','d','message'],index_col='message') Out[20]: a b c d message hello 1   2   3   4 world 5   6   7   8 foo 9  10  11  12

如果想讀取成分層索引,則需要為index_col參數傳入一個包含列序號或列名的列表:

# csv_mindex.csv key1,key2,value1,value2 one,a,1,2 one,b,3,4 one,c,5,6 one,d,7,8 two,a,9,10 two,b,11,12 two,c,13,14 two,d,15,16

分層索引類似多級索引,后面會介紹。

In [22]: df = pd.read_csv('d:/csv_mindex.csv', index_col=['key1','key2']) In [23]: df Out[23]: value1 value2 key1 key2 one a 1       2 b 3       4 c 5       6 d 7       8 two a 9      10 b 11      12 c 13      14 d 15      16

對於一些更復雜,或者說更不規整的文件,比如分隔符不固定的情況,需要有更多的處理技巧,比如下面這個文件,以不同數量的空格分隔:

# ex3.txt
 A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272  0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382  1.100491

這時候需要傳入一個正則表達式作為分隔符參數:

In [25]: result = pd.read_table('d:/ex3.txt', sep='\s+') In [26]: result Out[26]: A B C aaa -0.264438 -1.026059 -0.619500 bbb 0.927272  0.302904 -0.032399 ccc -0.264273 -0.386314 -0.217601 ddd -0.871858 -0.348382  1.100491

上面的正則表達式是\s+。並且由於列名比數據的列數少一個,系統自動推斷第一列應當作為行索引。

大多數讀取函數都帶有很多幫助我們處理各種異常情況的參數,比如可以使用skiprows來跳過數據中的指定行.

原始數據:

# hey!
a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway?
1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo

我們需要跳過無用的第1、3、4行廢話:

In [27]: pd.read_csv('d:/ex4.csv', skiprows=[0,2,3]) Out[27]: a b c d message 0 1   2   3   4 hello 1  5   6   7   8 world 2  9  10  11  12     foo

缺失值的處理是讀取數據時非常重要的部分。通常情況下,缺失值要么不顯示,直接空着,要么用一些標識值表示,比如NA或NULL。

看下面的數據,注意第三行的6和8之間有個空的:

something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo

read_csv會將缺失值自動讀成NaN:

In [30]: result = pd.read_csv('d:/ex5.csv') In [31]: result Out[31]: something a b c d message 0 one 1   2   3.0   4 NaN 1       two  5   6   NaN   8 world 2     three  9  10  11.0  12 foo In [32]: pd.isnull(result) Out[32]: something a b c d message 0 False False False False False True 1 False False False True False False 2      False  False  False  False  False    False

我們可以額外指定na_values參數,將某些值也當作缺失值來看待,比如下面我們將3.0也當作缺失值對待:

In [40]: result = pd.read_csv('d:/ex5.csv',na_values=[3.0]) In [41]: result Out[41]: something a b c d message 0 one 1   2   NaN   4 NaN 1       two  5   6   NaN   8 world 2     three  9  10  11.0  12     foo

甚至可以對不同的列,指定不同的缺失值標識:

In [42]: f = {'message':['foo','NA'],'something':['two']} In [43]: result = pd.read_csv('d:/ex5.csv',na_values=f) In [44]: result Out[44]: something a b c d message 0 one 1   2   3.0   4 NaN 1       NaN  5   6   NaN   8 world 2     three  9  10  11.0  12     NaN

下表列出了read_csvread_table函數的一些常用參數:

參數 說明
path 文件路徑
sep 指定分隔符或正則表達式
header 用作列名的行號
index_col 用作行索引的列名或列號
names 結果的列名列表
skiprows 從起始處,需要跳過的行
na_values 需要用NaN替換的值
comment 在行結尾處分隔注釋的字符
parse_dates 嘗試將數據解析為datetime,默認是False
keep_date_col 如果連接列到解析日期上,保留被連接的列,默認False
converters 包含列名稱映射到函數的字典
dayfirst 解析非明確日期時,按國際格式處理
date_parser 用於解析日期的函數
nrows 從文件開頭處讀入的行數
iterator 返回一個TextParser對象,用於零散地讀入文件
chunksize 用於迭代的塊大小
skip_footer 忽略文件尾部的行數
verbose 打印各種解析器輸出的信息
encoding 文本編碼,比如UTF-8
thousands 定義千位分隔符,例如逗號或者圓點

二、分塊讀取

當我們處理大型文件的時候,讀入文件的一個小片段或者按小塊遍歷文件是比較好的做法。

在這之前,我們最好先對Pandas的顯示設置進行調整,使之更為緊湊:

In [45]: pd.options.display.max_rows = 10

這樣,即使是大文件,最多也只會顯式10行具體內容。

In [46]: result = pd.read_csv('d:/ex6.csv') In [47]: result Out[47]: one two three four key 0 0.467976 -0.038649 -0.295344 -1.824726 L 1    -0.358893  1.404453  0.704965 -0.200638 B 2    -0.501840  0.659254 -0.421691 -0.057688 G 3     0.204886  1.074134  1.388361 -0.982404 R 4     0.354628 -0.133116  0.283763 -0.837063 Q ... ... ... ... ... .. 9995  2.311896 -0.417070 -1.409599 -0.515821 L 9996 -0.479893 -0.650419  0.745152 -0.646038 E 9997  0.523331  0.787112  0.486066  1.093156 K 9998 -0.362559  0.598894 -1.843201  0.887292 G 9999 -0.096376 -1.012999 -0.657431 -0.573315 0 [10000 rows x 5 columns]

或者使用nrows參數,指明從文件開頭往下只讀n行:

In [48]: result = pd.read_csv('d:/ex6.csv',nrows=5) In [49]: result Out[49]: one two three four key 0 0.467976 -0.038649 -0.295344 -1.824726 L 1 -0.358893  1.404453  0.704965 -0.200638 B 2 -0.501840  0.659254 -0.421691 -0.057688 G 3  0.204886  1.074134  1.388361 -0.982404 R 4  0.354628 -0.133116  0.283763 -0.837063   Q

或者指定chunksize作為每一塊的行數,分塊讀入文件:

In [50]: chunker = pd.read_csv('d:/ex6.csv', chunksize=1000) In [51]: chunker Out[51]: <pandas.io.parsers.TextFileReader at 0x2417d6cfb38>

上面的TextFileReader對象是一個可迭代對象。例如我們可以遍歷它,並對‘key’列進行聚合獲得計數值:

In [52]: total = pd.Series([]) In [53]: for piece in chunker: ...: total = total.add(piece['key'].value_counts(), fill_value=0) ...: total = total.sort_values(ascending=False) In [54]: total Out[54]: E 368.0 X 364.0 L 346.0 O 343.0 Q 340.0 ... 5    157.0
2    152.0 0 151.0
9    150.0
1    146.0 Length: 36, dtype: float64 In [55]: total[:10] Out[55]: E 368.0 X 364.0 L 346.0 O 343.0 Q 340.0 M 338.0 J 337.0 F 335.0 K 334.0 H 330.0 dtype: float64


免責聲明!

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



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