第06章 資料加載、存儲與檔案格式 pandas提供了一些用于将表格型資料讀取為DataFrame對象的函數。表1對它們進行了總結,其中read_csv和read_table可能會是你今後用得最多的。
利用Python進行資料分析第二版複現(五) import pandas as pd
import numpy as np
df = pd.read_csv('examples/ex1.csv')
df
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
#下面這個指令電腦不能用
#!cat examples/ex1.csv
對于沒有标題行的資料,可以通過header屬性或者names屬性進行标注,假設你希望将message列做成DataFrame的索引。你可以明确表示要将該列放到索引4的位置上,也可
以通過index_col參數指定"message"。
1 2 3 4 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
names = ['a', 'b', 'c', 'd', 'message']
pd.read_csv('examples/ex2.csv', names=names, index_col='message')
a b c d message hello 1 2 3 4 world 5 6 7 8 foo 9 10 11 12
parsed = pd.read_csv('examples/csv_mindex.csv',
index_col=['key1', 'key2'])
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
#有些表格可能不是用固定的分隔符去分隔字段的(比如空白符或其它模式)
list(open('examples/ex3.txt'))
[' A B C\n',
'aaa -0.264438 -1.026059 -0.619500\n',
'bbb 0.927272 0.302904 -0.032399\n',
'ccc -0.264273 -0.386314 -0.217601\n',
'ddd -0.871858 -0.348382 1.100491\n']
result = pd.read_table('examples/ex3.txt', sep='\s+')
result
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
#可以用skiprows跳過檔案的第一行、第三行和第四行
pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
result = pd.read_csv("examples/ex5.csv")
print(result)
pd.isnull(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
something a b c d message False False False False False True 1 False False False True False False 2 False False False False False False
pandas.read_csv和pandas.read_table常用的選項
利用Python進行資料分析第二版複現(五) 利用Python進行資料分析第二版複現(五) 逐塊讀取文本檔案 我們先設定pandas顯示地更緊些.
pd.options.display.max_rows = 10
result = pd.read_csv('examples/ex6.csv')
result
one two three four key 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
10000 rows × 5 columns
#隻想讀取幾行(避免讀取整個檔案),通過nrows進行指定即可:
pd.read_csv('examples/ex6.csv', nrows=5)
one two three four key 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(行數)
chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)
chunker
<pandas.io.parsers.TextFileReader at 0xb66a590>
chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)
tot = pd.Series([])
for piece in chunker:
tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.sort_values(ascending=False)
tot[:10]
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
将資料寫出到文本格式 利用DataFrame的to_csv用法,我們可以将資料寫到1個以逗号分隔的檔案中
data = pd.read_csv('examples/ex5.csv')
data.to_csv('examples/out2020.csv')
import sys
data.to_csv(sys.stdout, sep='|')
|something|a|b|c|d|message
0|one|1|2|3.0|4|
1|two|5|6||8|world
2|three|9|10|11.0|12|foo
#缺失值在輸出結果中會被表示為空字元串。你可能希望将其表示為别的标記值:
data.to_csv(sys.stdout, na_rep='NULL')
,something,a,b,c,d,message
0,one,1,2,3.0,4,NULL
1,two,5,6,NULL,8,world
2,three,9,10,11.0,12,foo
#如果沒有設定其他選項,則會寫出⾏和列的标簽。當然,它們也都可以被禁用
data.to_csv(sys.stdout, index=False, header=False)
one,1,2,3.0,4,
two,5,6,,8,world
three,9,10,11.0,12,foo
#可以隻寫出1部分的列,并以你指定的順序排列:
data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c'])
a,b,c
1,2,3.0
5,6,
9,10,11.0
9,10,11.0
處理分隔符格式 import csv
f = open('examples/ex7.csv')
reader = csv.reader(f)
#對這個reader進行疊代将會為每行産生一個元組(并移除了所有的引号):對這個reader進行疊代将會
#為每行産生一個元組(并移除了所有的引号):
for line in reader:
print(line)
with open('examples/ex7.csv') as f:
lines = list(csv.reader(f))
header, values = lines[0], lines[1:]
data_dict = {h: v for h, v in zip(header, zip(*values))}
data_dict
{'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}
csv語支選項
利用Python進行資料分析第二版複現(五) JSON資料 是1種比表格型文本格式(如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"]}]
}
"""
import json
result = json.loads(obj)
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)
#如何将(1個或1組)JSON對象轉換為DataFrame或其他便于分析的資料結構就由你決定了。最簡單
#友善的方式是:向DataFrame構造器傳入1個字典的清單(就是原先的JSON對象),并選取資料字段
#的子集
siblings = pd.DataFrame(result['siblings'], columns=['name', 'age'])
siblings
name age Scott 30 1 Katie 38
#pandas.read_json的預設選項假設JSON數組中的每個對象是表格中的一行
data = pd.read_json('examples/example.json')
data
a b c 1 2 3 1 4 5 6 2 7 8 9
6.2 二進制資料格式 實作資料的⾼效⼆進制格式存儲最簡單的辦法之1是使用Python内置的pickle序列化。pandas對象都有1個用于将資料以pickle格式儲存到磁盤上的to_pickle用法。
frame = pd.read_csv('examples/ex1.csv')
frame
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
frame.to_pickle('examples/frame_pickle')
pd.read_pickle('examples/frame_pickle')
a b c d message 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
#要使用ExcelFile,通過傳遞xls或xlsx路徑建立1個執行個體:
xlsx = pd.ExcelFile('examples/ex1.xlsx')
pd.read_excel(xlsx, 'Sheet1')
Unnamed: 0 a b c d message 1 2 3 4 hello 1 1 5 6 7 8 world 2 2 9 10 11 12 foo
frame = pd.read_excel('examples/ex1.xlsx', 'Sheet1')
frame
Unnamed: 0 a b c d message 1 2 3 4 hello 1 1 5 6 7 8 world 2 2 9 10 11 12 foo
#如果要将pandas資料寫入為Excel格式,你必須首先建立1個ExcelWriter,然後使用andas對象的
#to_excel方法将資料寫入到其中:
writer = pd.ExcelWriter('examples/ex2020.xlsx')
frame.to_excel(writer, 'Sheet1')
writer.save()
#還可以不使用ExcelWriter,而是傳遞檔案的路徑到to_excel:
frame.to_excel('examples/ex2019.xlsx')
6.3 Web APIs互動 使用requests包
import requests
url = 'https://api.github.com/repos/pandas-dev/pandas/issues'
resp = requests.get(url)
resp
<Response [200]>
data = resp.json()
data[0]['title']
"DOC: Fix the description of the 'day' field accessor in DatetimeArray"
issues = pd.DataFrame(data, columns=['number', 'title',
'labels', 'state'])
issues
number title labels state 31490 DOC: Fix the description of the 'day' field ac... [] open 1 31489 ~ operator on Series with BooleanDtype casts t... [] open 2 31488 Unclosed file on EmptyDataError [] open 3 31487 Maybe wrong default axis with operators (add, ... [] open 4 31486 DOC: Parameter doc strings for Groupby.(sum|pr... [] open ... ... ... ... ... 25 31459 ENH: pd.cut should be able to return a Series ... [{'id': 76812, 'node_id': 'MDU6TGFiZWw3NjgxMg=... open 26 31458 Fix to_csv and to_excel links on read_csv, rea... [] open 27 31457 Timedelta multiplication crashes for large arrays [{'id': 47223669, 'node_id': 'MDU6TGFiZWw0NzIy... open 28 31456 BUG: Groupby.apply wasn't allowing for functio... [{'id': 233160, 'node_id': 'MDU6TGFiZWwyMzMxNj... open 29 31455 jobs failling with error raise RuntimeError("C... [{'id': 307649777, 'node_id': 'MDU6TGFiZWwzMDc... open
30 rows × 4 columns
6.4 資料庫互動 在商業場景下,大多數資料可能不是存儲在文本或Excel檔案中。基于SQL的關系型資料庫(如SQLServer、PostgreSQL和MySQL等)使用非常廣泛,其它⼀些資料庫也很流行。資料庫的選擇通常取決于性能、資料完整性以及應⽤程式的伸縮性需求。
将資料從SQL加載到DataFrame的過程很簡單,此外pandas還有1些能夠簡化該過程的函數。例如,我将使用SQLite資料庫(通過Python内置的sqlite3驅動器)。
import sqlite3
query = """
CREATE TABLE test
(a VARCHAR(20), b VARCHAR(20),
c REAL, d INTEGER
);"""
con = sqlite3.connect('mydata.sqlite')
con.execute(query)
con.commit()
data = [('Atlanta', 'Georgia', 1.25, 6),
('Tallahassee', 'Florida', 2.6, 3),
('Sacramento', 'California', 1.7, 5)]
stmt = "INSERT INTO test VALUES(?, ?, ?, ?)"
con.executemany(stmt, data)
<sqlite3.Cursor at 0xe49e5a0>
cursor = con.execute('select * from test')
rows = cursor.fetchall()
rows
[('Atlanta', 'Georgia', 1.25, 6),
('Tallahassee', 'Florida', 2.6, 3),
('Sacramento', 'California', 1.7, 5)]
cursor.description
(('a', None, None, None, None, None, None),
('b', None, None, None, None, None, None),
('c', None, None, None, None, None, None),
('d', None, None, None, None, None, None))
a b c d Atlanta Georgia 1.25 6 1 Tallahassee Florida 2.60 3 2 Sacramento California 1.70 5
import sqlalchemy as sqla
db = sqla.create_engine('sqlite:///mydata.sqlite')
pd.read_sql('select * from test', db)