Python之數據載入、存儲及文件格式

本博客爲《利用Python進行數據分析》的讀書筆記,請勿轉載用於其他商業用途。

1. 文本格式數據的讀寫

輸入和輸出通常有以下幾種類型:

  • 讀取文本文件及硬盤上其他更高效的格式文件
  • 從數據庫載入數據
  • 與網絡資源進行交互(比如Web API)

將表格類型數據讀取爲DataFrame對象是pandas的重要特性。下表總結了部分實現該功能的函數,read_csvread_table可能是後期我們使用最多的函數。

表:Pandas的解析函數

函數 描述
read_csv 從文件、URL或文件型對象讀取分隔好的數據,逗號是默認分隔符
read_table 從文件、URL或文件型對象讀取分隔好的數據,製表符(‘t/’)是默認分隔符
read_fwf 從特定寬度格式的文件中讀取數據(無分隔符)
read_clipboard read_table的剪貼版本,在將表格從Web頁面上轉換成數據時有用
read_excel 從Excel的XLS或XLSX文件中讀取表格數據
read_hdf 讀取用pandas存儲的HDF5文件
read_html 從HTML文件中讀取所有表格數據
read_json 從JSON(JavaScript Object No tation)字符串中讀取數據
read_msgpack 讀取MessagePack二進制格式的pandas數據
read_pickle 讀取以Python pickle格式存儲的任意對象
read_sas 讀取存儲在SAS系統中定製存儲格式的SAS數據集
read_sql 將SQL查詢的結果(使用SQLAlchemy)讀取爲pandas的DataFrame
read_stata 讀取Stata格式的數據集
read_feather 讀取Feather二進制格式

這些函數的可選參數主要有以下幾種類型:

  • 索引
    可以將一或多個列作爲返回的DataFrame,從文件或用戶處獲得列名,或者沒有列名。
  • 類型推斷和數據轉換
    包括用戶自定義的值轉換和自定義的缺失值符號列表
  • 日期時間解析
    包括組合功能,也包括將分散在多個列上的日期和時間信息組合成結果中的單個列。
  • 迭代
    支持對大型文件的分塊迭代。
  • 未清洗數據問題
    跳過行、頁腳、註釋以及其他次要數據,比如使用逗號分隔千位的數字。

由於現實世界中的數據非常混亂,隨着時間推移,一些數據加載函數(尤其是read_csv)的可選參數變得非常複雜。pandas的在線文檔有大量示例展示這些參數是如何工作的。如果你在讀取某個文件時遇到了困難,在文檔中可能會有相似的示例幫助你如何找到正確的參數。
一些數據載入函數,比如pandas.read_csv,會進行類型推斷,因爲列的數據類型並不是數據格式的一部分。那就意味着我們不必指定哪一列時數值、整數、布爾值或字符串。其他的數據格式,比如HDF5、Feather和msgpack在格式中已經存儲了數據類型。
處理日期和其他自定義類型可能需要額外的努力。我們從一個小型的逗號分隔符文本文件(csv)開始:
csv文件的內容大概這個樣子
由於這個文件時逗號分隔的,我們可以使用read_csv將它讀入一個DataFrame:

df = pd.read_csv('C:/ex1.csv')
print(df)
#
   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,並制定分隔符:

df = pd.read_table('C:/ex1.csv', sep=',')
print(df)
#
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo

有些文件並不包含表頭,比如:
在這裏插入圖片描述
要讀取該文件,我們需要選擇一些選項。你可以允許pandas自動分配默認列名,也可以自己指定列名:

df = pd.read_csv('C:/ex2.csv', header=None)
print(df)
#
   0   1   2   3      4
0  1   2   3   4  hello
1  5   6   7   8  world
2  9  10  11  12    foo
df = pd.read_csv('C:/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])
print(df)
#
   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的索引,可以指定位置4的列爲索引,或將’message’傳給參數index_col

names = ['a', 'b', 'c', 'd', 'message']
df = pd.read_csv('C:/ex2.csv', names=names, index_col='message')
print(df)
#
         a   b   c   d
message               
hello    1   2   3   4
world    5   6   7   8
foo      9  10  11  12

如果我們想要從多個列中形成一個分層索引,需要傳入一個包含序列號或列名的列表:
在這裏插入圖片描述

parsed = pd.read_csv('C:/csv_mindex.csv', index_col=['key1', 'key2'])
print(parsed)
#
           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

在某些情況下,一張表的分隔符並不是固定的,使用空白或其他方式來分隔字段,考慮如下文本文件:
在這裏插入圖片描述

data = list(open('C:/ex3.txt'))
print(data)
#
['\tA\tB\tC\n', 
'aaa\t1\t2\t3\n', 
'bbb\t4\t5\t6\n', 
'ccc\t7\t8\t9\n', 
'ddd\t10\t11\t12\n']
result = pd.read_table('C:/ex3.txt', sep='\s+')
print(result)
#
      A   B   C
aaa   1   2   3
bbb   4   5   6
ccc   7   8   9
ddd  10  11  12

本例中,由於列名的數量比數據的列少一個,因此read_table推斷第一列應當作爲DataFrame的索引。
解析函數有很多附加參數幫助你處理各種發生異常的文件格式。例如,你可以使用skiprows來跳過第1、3、4行:
在這裏插入圖片描述

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

缺失值處理是文件解析過程中一個重要且常常微妙的部分。通常情況下,缺失值要麼不顯示(空字符串),要麼用一些標識值。默認情況下,pandas使用一些常見的標識,例如NA和NULL:
在這裏插入圖片描述

result = pd.read_csv('C:/ex5.csv')
print(result)
#
  something  a   b   c   d message
0       one  1   2   3   4     NaN
1       two  5   6   7   8   world
2     three  9  10  11  12     foo
print(pd.isnull(result))
#
   something      a      b      c      d  message
0      False  False  False  False  False     True
1      False  False  False  False  False    False
2      False  False  False  False  False    False

na_values選項可以傳入一個列表或一組字符串來處理缺失值:

result = pd.read_csv('C:/ex5.csv', na_values=['NULL'])
print(result)
#
  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

在字典中,每列可以指定不同的缺失值標識:

sentinels = {'message': ['foo', 'NA'], 'something': ['two']}
data = pd.read_csv('C:/ex5.csv', na_values=sentinels)
print(data)
#
  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

下表列舉了pandas.read_csvpandas.read_table中常用的選項。

表:一些read_csv / read_table函數參數

參數 描述
path 表明文件系統位置的字符串,URL或文件類型
sep或delimiter 用於分隔每行字段的字符序列或正則表達式
header 用作列名的行號,默認是0(第一行),如果沒有列名的話,應該爲None
index_col 用作結果中行索引的列號或列名,可以是一個單一的名稱/數字,也可以是一個分層索引
names 結果的列名列表,和header=None一起使用
skiprows 從文件開頭處起,需要跳過的行數或行號列表
na_values 需要用NA替換的序列值
comment 在行結尾處分隔註釋的字符
parse_dates 嘗試將數據解析爲datetime,默認是False。如果爲True,將嘗試解析所有的列。也可以指定列號或列名列表來進行解析。如果列表的元素是元組或列表,將會把多個列組合在一起進行解析(如日期/時間將拆分爲兩列)
keep_date_col 如果連接列到解析日期上,保留被連接的列,默認是False
converters 包含列名稱映射到函數的字典(例如{‘foo’: f}會把函數f應用到‘foo’列)
dayfirst 解析非明確日期時,按照國際格式處理(例如7/6/2012 ->June 7, 2012),默認爲False
date_parser 用於解析日期的函數
nrows 從文件開頭處讀入的行數
iterator 返回一個TextParser對象,用於零散地讀入文件
chunksize 用於迭代的塊大小
skip_footer 忽略文件尾部的行數
verbose 打印各種解析器輸出的信息,比如位於非數值列中的缺失值數量
encoding Unicode文本編碼(例如‘utf-8’用於表示UTF-8編碼的文本)
squeeze 如果解析數據只包含一列,返回一個Series
thousands 千位分隔符(例如‘,’或‘.’)

1.1 分塊讀入文本文件

當處理大型文件或找出正確的參數集來正確處理大文件時,我們可能需要讀入文件的一個小片段或者按小塊遍歷文件。
在嘗試大文件之前,我們可以先對pandas的現實設置進行調整,使之更爲緊湊:

pd.options.display.max_rows = 10

現在我們可以得到:

result = pd.read_csv('C:/ex6.csv')
print(result)
#
      one    two  three   four key
0    0.12  -0.34   0.56  -0.78   A
1    1.12   0.66   1.56   0.22   J
2    2.12   1.66   2.56   1.22   L
3    3.12   2.66   3.56   2.22   F
4    4.12   3.66   4.56   3.22   B
..    ...    ...    ...    ...  ..
94  94.12  93.66  94.56  93.22   T
95  95.12  94.66  95.56  94.22   R
96  96.12  95.66  96.56  95.22   E
97  97.12  96.66  97.56  96.22   W
98  98.12  97.66  98.56  97.22   Q

[99 rows x 5 columns]

如果你只想讀取一小部分(避免讀取整個文件),可以指明nrows

result = pd.read_csv('C:/ex6.csv', nrows=5)
print(result)
#
    one   two  three  four key
0  0.12 -0.34   0.56 -0.78   A
1  1.12  0.66   1.56  0.22   J
2  2.12  1.66   2.56  1.22   L
3  3.12  2.66   3.56  2.22   F
4  4.12  3.66   4.56  3.22   B

爲了分塊讀入文件,可以指定chunksize作爲每一塊的行數:

chunker = pd.read_csv('ex6.csv', chunksize=50)
print(chunker)
#
<pandas.io.parsers.TextFileReader object at 0x02F6F8B0>

read_csv返回的TextParser對象允許你根據chunksize遍歷文件。例如,我們可以遍歷ex6.csv,並對’key’列聚合獲得計數值:

chunker = pd.read_csv('ex6.csv', chunksize=50)
tot = pd.Series([])
for piece in chunker:
    tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.sort_values(ascending=False)
print(tot[:10])

#
L    13.0
R    11.0
E    11.0
Y     6.0
T     6.0
Q     6.0
W     6.0
I     5.0
C     5.0
G     5.0
dtype: float64

該代碼的意思是,在key列中,以上字母共出現了多少次。
TextParser還具有get_chunk方法,允許你按照任意大小讀取數據塊。

1.2 將數據寫入文本格式

數據可以導出爲分隔的形式:

data = pd.read_csv('ex5.csv')
print(data)

#
  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

使用DataFrame的to_csv方法,我們可以將數據導出爲逗號分隔的文件:
略。
當然,其他的分隔符也是可以的(寫入到sys.stdout時,控制檯中打印機的文本結果):

import sys
result = data.to_csv(sys.stdout, sep='|')
print(result)

#
|Unnamed: 0|something|a|b|c|d|message
0|0|one|1|2|3.0|4|
1|1|two|5|6||8|world
2|2|three|9|10|11.0|12|foo

缺失值在輸出時以空字符串出現。你也許想要用其他標識值對缺失值進行標註:

result = data.to_csv(sys.stdout, na_rep='NULL')
print(result)

#
,Unnamed: 0,something,a,b,c,d,message
0,0,one,1,2,3.0,4,NULL
1,1,two,5,6,NULL,8,world
2,2,three,9,10,11.0,12,foo

如果沒有其他按選項被指定的話,行和列的標籤都會被寫入。不過二者也都可以禁止寫入:

result = data.to_csv(sys.stdout, index=False, header=False)
print(result)

#
0,one,1,2,3.0,4,
1,two,5,6,,8,world
2,three,9,10,11.0,12,foo
None

你也可以僅寫入列的子集,並且按照你選擇的順序寫入:

result = data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c'])
print(result)

#
a,b,c
1,2,3.0
5,6,
9,10,11.0
None

1.3 使用分隔格式

絕大多數的表型數據都可以使用函數pandas.read_table從硬盤中讀出。然而,在某些情況下,一些手動操作可能是必不可少的。接受一個帶有一行或者多行錯誤的文件並不少見,read_table也無法解決這種情況。爲了介紹一些基礎工具,考慮如下的小型csv文件:
在這裏插入圖片描述
對於任何帶有單字符分隔符的文件,我們可以使用Python內置的內建csv模塊。要使用它,需要將任一打開的文件或文件類型對象傳給csv.reader

import csv
f = open('ex7.csv')
reader = csv.reader(f)

像遍歷文件那樣遍歷reader會產生元組,元組的值爲刪除了引號的字符:

import csv
f = open('ex7.csv')
reader = csv.reader(f)
for line in reader:
    print(line)
    
#
['"a"', '"b"', '"c"']
['"1"', '"2"', '"3"']
['"1"', '"2"', '"3"']    

按照書中的操作,理論上應該得到去掉雙引號的字符,然而事實並不是這樣的……不管了,我們繼續。

表:CSV方言選項

參數 描述
delimiter 一個用於分隔字段的字符,默認是‘,’
lineterminator 行終止符,默認是‘\r\n’,讀取器會忽略行終止符並識別跨平臺行終止符
quotechar 用在含有特殊字符字段中的引號,默認是’ " ’
quoting 引用慣例。選項包括csv.QUOTE_ALL(引用所有的字段),cdv.QUOTE_MINIMAL(只使用特殊字符,如分隔符),csv.QUOTE_NONNUMERICcsv.QUOTE_NONE(不引用)。細節請參考Python的文檔。默認是QUOTE_MINIMAL
skipinitialspace 忽略每個分隔符後的空白,默認是False
doublequote 如何處理字段內部的引號。如果爲True,則是雙引號
escapechar 當引用設置爲csv.QUOTE_NONE時用於轉移分隔符的字符串,默認是禁用的

對於具有更復雜或固定的多字符分隔符的文件,你將無法使用csv模塊。在此類情況下,你將不得不使用字符串的split方法或正則表達式方法re.split進行行拆分和其他清理工作。

需要手動寫入被分隔的文件時,可以使用csv.writer。這個函數接受一個已經打開的可寫入文件對象以及和csv.reader相同的CSV方言、格式選項:

with open('mydata.csv', 'w')as f:
    writer = csv.writer(f, dialect=my_dialect)
    writer.writerow(('one', 'two', 'three'))
    writer.writerow(('1', '2', '3'))
    writer.writerow(('4', '5', '6'))
    writer.writerow(('7', '8', '9'))

1.4 JSON數據

JSON(JavaScript Object Notation)已經成爲Web瀏覽器和其他應用間通過HTTP請求發送數據的標準格式。它是一種比CSV表格文本形式更爲自由的數據形式。請看下面的例子:

obj = """
{"name":"Wes",
"places_lived": ["United States", "Spain", "Germany"],
"pet": null
"siblings":[{"name":"Scott", "age":30, "pets":["Zeus", "Zuko"]},
            {"name":"Katie", "age":38,
            "pets":["Sixes", "Stache", "Cisco"]}]
}
"""

JSON非常接近有效的Python代碼,除了它的值null和一些其他的細微差別(例如不允許列表末尾的逗號)之外。基本類型是對象(字典)、數組(列表)、字符串、數字、布爾值和空值。對象中的所有鍵必須是字符串。有幾個Python庫用於讀寫JSON數據。我們將在這裏使用json,因爲它是內置在Python標準庫中的。將JSON字符串轉換爲Python時,使用json.loads方法:

import json
result = json.loads(obj)
print(result)

#
{'name': 'Wes', 'places_lived': ['United States', 'Spain', 'Germany'],
'pet': None, 'siblings': [{'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']},
{'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]}

另一方面,json.dumps方法可以將Python對象轉換爲JSON:

asjson = json.dumps(result)

你將自行決定如何將JSON對象或對象列表轉換爲DataFrame或其他數據結構。比較方便的方式是將字典構成的列表(之前是JSON對象)傳入DataFrame構造函數,並選出數據字段的子集:

siblings = pd.DataFrame(result['siblings'], columns=['name', 'age'])
print(siblings)

#
    name  age
0  Scott   30
1  Katie   38

pandas.read_json可以自動將JSON數據集按照指定次序轉換爲Series或DataFrame。
首先我們創建一個JSON文件:
在這裏插入圖片描述
pandas.read_json的默認選項是假設JSON數組中的沒個對象是表裏的一行:

data = pd.read_csv('example.json')
print(data)
#
   [{"a": 1   "b": 2    "c": 3}  Unnamed: 3
0   {"a": 4   "b": 5    "c": 6}         NaN
1   {"a": 7   "b": 8   "c": 9}]         NaN

得到是這個鬼東西……跟書上的不一樣啊……算了……
如果需要從pandas中將數據導出爲JSON,一種辦法是對Series和DataFrame使用to_json方法:

print(data.to_json())

1.5 XML和HTML:網絡抓取

Python擁有很多可以對HTML和XML格式進行讀取、寫入數據的庫。例如lxml、Beautiful Soup和htmal5lib。儘管lxml是相對更快的庫,但其他庫可以更好地處理異常的HTML和XML文件。
pandas的內建函數read_hml可以使用lxml和Beautiful Soup等庫將HTML中的表自動解析爲DataFrame對象。爲了展示這個功能,我們從美國FDIC政府機構下載了顯示銀行倒閉數據的HTML文件(在pandas文檔中使用)。
在這裏插入圖片描述
pandas.read_html函數有很多選項,但是默認情況下,它會搜索並嘗試解析所有包含在<table>標籤中的表格型數據,返回的結果是DataFrame對象的列表:

tables = pd.read_html('FDIC_ Failed Bank List.html')
print(len(tables))

#
1
failures = tables[0]
print(failures)
#
 Bank Name  ...       Closing Date
0       City National Bank of New Jersey  ...   November 1, 2019
1                          Resolute Bank  ...   October 25, 2019
2                  Louisa Community Bank  ...   October 25, 2019
3                   The Enloe State Bank  ...       May 31, 2019
4    Washington Federal Bank for Savings  ...  December 15, 2017
..                                   ...  ...                ...
554                   Superior Bank, FSB  ...      July 27, 2001
555                  Malta National Bank  ...        May 3, 2001
556      First Alliance Bank & Trust Co.  ...   February 2, 2001
557    National State Bank of Metropolis  ...  December 14, 2000
558                     Bank of Honolulu  ...   October 13, 2000

[559 rows x 6 columns]

以上是Pycharm顯示的結果,我們再看下Conda顯示的結果:
在這裏插入圖片描述
我去,愛了愛了……
此處我們可以着手一些數據清理和分析工作,比如計算每年銀行倒閉的數量:

close_timestamps = pd.to_datetime(failures['Closing Date'])
print(close_timestamps.dt.year.value_counts())

#
2010    157
2009    140
2011     92
2012     51
2008     25
2013     24
2014     18
2002     11
2015      8
2017      8
2016      5
2001      4
2019      4
2004      4
2003      3
2007      3
2000      2
Name: Closing Date, dtype: int64

2. 二進制格式

使用Python內建的pickle序列化模塊進行二進制格式操作時存儲數據(也稱爲序列化)最高效、最方便的方式之一。pandas對象擁有一個to_pickle方法可以將數據以pickle格式寫入硬盤:

frame = pd.read_csv('ex1.csv')
print(frame)

#
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo
frame.to_pickle('frame_picke')

我們直接使用內建的pickle讀取文件中“pickle”化的對象,或更方便地使用pandas.read_pickle做上述操作:

data = pd.read_pickle('frame_pickle')
print(data)

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

注意:pickle僅被推薦作爲短期的存儲格式。問題在於pickle很難確保格式的長期有效性;一個今天被pickle化的對象可能明天因爲庫的新版本而無法反序列化。

pandas內建支持其他兩個二進制格式:HDF5和MessagePack。

2.1 使用HDF5格式

HDF5是一個備受好評的文件格式,用於存儲大量的科學數組數據。它以C庫的形式提供,並且具有許多其他語言的接口,包括Java、Julia、MATLAB和Python。HDF5中的“HDF”代表分層數據格式。每個HDF5文件可以存儲多個數據集並且支持元數據。與更簡單格式相比,HDF5支持多種壓縮模式的即時壓縮,是的重複模式的數據可以更高第存儲。HDF5適用於處理不適合在內存中存儲的超大型數據,可以使你高效讀寫大型數組的一小塊。
儘快可以通過使用Pytables或h5py等庫直接訪問HDF5文件,但pandas提供了一個高階的接口,可以簡化Series和DataFrame的存儲。HDFStore類像字典一樣工作並處理低級別細節:

frame = pd.DataFrame({'a': np.random.randn(100)})
store = pd.HDFStore('mydata.h5')
store['obj1'] = frame
store['obj1_col'] = frame['a']
store
#
<class 'pandas.io.pytables.HDFStore'>
File path: mydata.h5

結果跟書上還是有一些差距。
包含在HD5文件中的對象可以使用相同的字典型API進行檢索:

store['obj1']
#
	       a
0	0.779202
1	-1.077735
2	0.028898
3	-0.050125
4	0.477923
5	-2.152421
6	0.639740
7	-0.786466
8	-1.091780
9	0.606801
10	-0.489952
11	1.124520
12	-0.700125
13	0.702218
14	-1.729623
15	0.391208
16	-1.409342
17	0.565409
18	-0.985509
19	2.000896
20	1.498629
21	2.446517
22	0.889966
23	-1.171885
24	1.115902
25	-0.400008
26	-1.439171
27	-0.457836
28	1.790552
29	0.615969
...	...
70	-0.004149
71	0.730181
72	0.615633
73	-1.425845
74	0.116927
75	0.853079
76	0.462751
77	0.952087
78	-0.853721
79	0.144893
80	-0.485946
81	0.035803
82	1.812239
83	1.682183
84	-1.364205
85	1.349751
86	0.057801
87	0.310320
88	-0.091248
89	-0.197712
90	-1.018919
91	-1.330481
92	-1.133903
93	-0.773132
94	-0.320451
95	-1.131031
96	-0.373055
97	-0.844670
98	-1.377580
99	0.263320
100 rows × 1 columns

HDFStore支持兩種存儲格式,'fixed''table'。後者速度更慢,但支持一種特殊語法的查詢操作:

store.put('obj2', frame, format='table')
store.select('obj2', where=['index >= 10 and index <= 15'])
store.close()
#
            a
10	-0.489952
11	1.124520
12	-0.700125
13	0.702218
14	-1.729623
15	0.391208

putstore['obj2']=frame方法的顯示版本,但允許我們設置其他選項,如存儲格式。
pandas.read_hdf函數是這些工具的快捷方法:

frame.to_hdf('mydata.h5', 'obj3', format='table')
print(pd.read_hdf('mydata.h5', 'obj3', where=['index < 5']))
#
           a
0	0.779202
1	-1.077735
2	0.028898
3	-0.050125
4	0.477923
5	-2.152421

如果你處理存儲在遠程服務器上的數據時,比如Amazon S3或HDFS,使用其他專門爲分佈式存儲而設計的二進制格式更爲合適,比如Apache Parquet。Parquet和其他類似的存儲格式仍然在發展中。
如果你是在本地處理大量數據,推薦嘗試PyTables和h5py,看看他們是否符合需求。由於很多數據分析的困難在於I/O密集(而非CPU密集),使用像HDF5這樣的工具可以大大加速你的應用。
HDF5並不是數據庫,它是一種適合一次寫入多次讀取的數據集。儘管數據可以在任何時間添加到文件中,但如果多個寫入者持續寫入,文件可能會損壞。

2.2 讀取Microsoft Excel文件

pandas也支持通過ExcelFile類或pandas.read_excel函數來讀取存儲在Excel 2003(或更高版本)文件中的表格類型數據。這些工具內部是使用附加包xlrdopenpyxl來分別讀取XLS和XLSX文件的。你可能需要使用pip或conda手動安裝這些工具。
使用ExcelFile時,通過將xls或xlsx的路徑傳入,生成一個實例:

xlsx = pd.ExcelFile('ex1.xlsx')
data = pd.read_excel(xlsx, 'Sheet1')
print(data)

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

如果你讀取的是含有多個表的文件,生成ExcelFile更快,但你也可以更簡潔地將文件名傳入pandas.read_excel

frame = pd.read_excel('ex1.xlsx', 'Sheet1')
print(frame)

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

如需將pandas數據寫入到Excel格式中,必須先生成一個ExcelWriter,然後使用pandas對象的to_excel方法將數據寫入:
在這裏插入圖片描述

writer = pd.ExcelWriter('ex2.xlsx', 'Sheet1')
frame.to_excel(writer, 'Sheet1')
writer.save()

我們也可以將文件路徑傳給to_excel,避免直接調用ExcelWriter

frame.to_excel('ex2.xlsx')

3. 與Web API交互

很多網站都有公開API,通過JSON或其他格式提供數據服務。有多種方式可以利用Python來訪問API。我推薦的簡單易用方式是使用requests包。要獲取GitHub上最新的30條關於pandas的問題,我們可以使用附加庫requests發送一個HTTP GET請求:

import requests

url = 'https://api.github.com/repos/pandas-dev/pandas/issues'
resp = requests.get(url)
print(resp)

#
<Response [200]>

Response(響應)對象json方法將返回一個包含解析爲本地Python對象的JSON的字典。

data = resp.json()
print(data[0]['title'])

#
TST: expand tests for ExtensionArray setitem with nullable arrays

data中的每個元素都是一個包含GitHub問題頁面上所有數據的字典(註釋除外)。我們可以將data直接傳給DataFrame,並提取感興趣的字段:

issues = pd.DataFrame(data, columns=['numbers', 'title', 'labels', 'state'])
print(issues)

結果如下圖:
在這裏插入圖片描述
通過一些複雜操作,我們可以創建一些更高階的接口來訪問常用的Web API,以返回DataFrame對象以便於分析。

4. 與數據庫交互

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章