一、CSV使用
1 CSV文件讀取
逗號分隔值(Comma-Separated Values,CSV,有時也稱爲字符分隔值,因爲分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。純文本意味着該文件是一個字符序列,不含必須像二進制數字那樣被解讀的數據。
假設現在有筆資料檔案(jamesbond.csv),Film,Year,Actor,Director,Box Office,Budget,Bond Actor Salary
爲header
,其餘爲資料內容,如下:
Film,Year,Actor,Director,Box Office,Budget,Bond Actor Salary
Dr. No,1962,Sean Connery,Terence Young,448.8,7,0.6
From Russia with Love,1963,Sean Connery,Terence Young,543.8,12.6,1.6
Goldfinger,1964,Sean Connery,Guy Hamilton,820.4,18.6,3.2
Thunderball,1965,Sean Connery,Terence Young,848.1,41.9,4.7
...
接着用open()
開啓它,並用csv.reader()返回一個reader對象,利用該對象遍歷csv文件中的行:
import csv
with open('jamesbond.csv') as f:
myCsv = csv.reader(f)
headers = next(myCsv)
...
next()函數返回迭代器中的下一項。您可以添加一個默認的返回值,以在迭代結束時返回。
這裏next()
用來讀取下一行的資料,而csv
的第一行爲header。
********************************************************************************************************************************************
這裏詳細說明一下next()的作用,相當於將迭代器iterator中的指針向後移動,將已經輸出的元素pop掉。
比如:
a=iter(['Numer',1,2,3,4]
first_element=next(a) #此時first_element=‘Numer’
for i in a:
print(a)
#輸出:
1
2
3
4
********************************************************************************************************************************************
用for循環
讀取csv每一行的資料:
import csv
with open('jamesbond.csv') as f:
myCsv = csv.reader(f)
headers = next(myCsv) #讀取首行
for row in myCsv:
print(row)
可以看到每次輸出row
爲list
的資料型態:
'Dr. No', '1962', 'Sean Connery', 'Terence Young', '448.8', '7', '0.6']
['From Russia with Love', '1963', 'Sean Connery', 'Terence Young', '543.8', '12.6', '1.6']
['Goldfinger', '1964', 'Sean Connery', 'Guy Hamilton', '820.4', '18.6', '3.2']
['Thunderball', '1965', 'Sean Connery', 'Terence Young', '848.1', '41.9', '4.7']
因此,可以用讀取list的方式分別讀取裏面的值,像是row[0]
讀取Film
的資料,這裏就自己嘗試看看吧!
還有另外一種讀取方式的方法,可以將資料轉爲Dictionary
格式:
import csv
with open('./jamesbond.csv') as f:
myCsvDic = csv.DictReader(f)
for row in myCsvDic:
print(row['Film'])
print(row)
可以看到像是OrderedDict([('Film', 'Dr. No'), ('Year', '1962'), ('Actor', 'Sean Connery'), ('Director', 'Terence Young'), ('Box Office', '448.8'), ('Budget', '7'), ('Bond Actor Salary', '0.6')])
的內容,可以看到它是一個OrderedDict的物件型態,可以用取得Dictionary Value的方式取值,key
就是header
,上面範例中我們取每行row的Film
。
2 CSV文件寫入
前面都是說明如何讀取
,現在,就要說明寫入
的部分了!
- 首先先定義要寫入的資料,一般來說,csv需要第一行一行header來定義有哪些column,用
list
的格式儲存有哪些欄位。 - 每一行
row
用tuple
的方式並全部放在一個list裏面。 - 我們就以剛剛的資料來當範例,如下:
headers = ['Film', 'Year', 'Actor', 'Director', 'Box Office', 'Budget', 'Bond Actor Salary']
rows = [('Film', 'Dr. No'), ('Year', '1962'), ('Actor', 'Sean Connery'), ('Director', 'Terence Young'), ('Box Office', '448.8'), ('Budget', '7'), ('Bond Actor Salary', '0.6'),
('Film', 'From Russia with Love'), ('Year', '1963'), ('Actor', 'Sean Connery'), ('Director', 'Terence Young'), ('Box Office', '543.8'), ('Budget', '12.6'), ('Bond Actor Salary', '1.6'),
('Film', 'Goldfinger'), ('Year', '1964'), ('Actor', 'Sean Connery'), ('Director', 'Guy Hamilton'), ('Box Office', '820.4'), ('Budget', '18.6'), ('Bond Actor Salary', '3.2'),]
再來就是寫入檔案了,先用writer()
,先寫入第一行headers
,再把資料內容rows
寫入:
with open('writedFile.csv','w') as f:
writeCsv = csv.writer(f)
writeCsv.writerow(headers)
writeCsv.writerows(rows)
除了上面的方式,也可以使用DictWriter()
,直接定義headers並可以將資料以Dictionary方式寫入。只要將所有的資料(dic)存在一個list
內,用writerows()
。
rows = [{'Film':'Dr. No','Year': '1962', 'Actor': 'Sean Connery', 'Director': 'Terence Young', 'Box Office': '448.8', 'Budget':'7', 'Bond Actor Salary': '0.6'},
{'Film': 'From Russia with Love', 'Year': '1963', 'Actor': 'Sean Connery', 'Director': 'Terence Young', 'Box Office': '543.8', 'Budget': '12.6', 'Bond Actor Salary': '1.6'},
{'Film': 'Goldfinger', 'Year': '1964', 'Actor': 'Sean Connery', 'Director': 'Guy Hamilton', 'Box Office': '820.4', 'Budget': '18.6', 'Bond Actor Salary': '3.2'}]
with open('writedFile.csv','w') as f:
writedCsv = csv.DictWriter(f, headers)
writedCsv.writeheader()
writedCsv.writerows(rows)
3 分隔符
這裏說明一下dialect
,編碼風格,默認爲逗點(,)分隔,不過也支援自定義,只要透過register_dialect
方法。
register_dialect()
delimiter
: 分隔符號,默認爲逗號。name
: 爲dialect的名稱
csv.register_dialect('myDialect', delimiter='|', quoting=csv.QUOTE_ALL)
範例:
- 建立一個
myTextFile.csv
檔案,內容:
Film|Year|Actor|Director|Box Office|Budget|Bond Actor Salary
Dr. No|1962|Sean Connery|Terence Young|448.8|7|0.6
From Russia with Love|1963|Sean Connery|Terence Young|543.8|12.6|1.6
Goldfinger|1964|Sean Connery|Guy Hamilton|820.4|18.6|3.2
- 代碼:
with open('./myTextFile.csv','r') as f:
csv.register_dialect('my_delimite', delimiter='|', quoting=csv.QUOTE_ALL)
lines = csv.reader(f, 'my_delimite')
for line in lines:
print(line)
# output
#['Film', 'Year', 'Actor', 'Director', 'Box Office', 'Budget', 'Bond Actor Salary']
# ['Dr. No', '1962', 'Sean Connery', 'Terence Young', '448.8', '7', '0.6']
# ['From Russia with Love', '1963', 'Sean Connery', 'Terence Young', '543.8', '12.6', '1.6']
# ['Goldfinger', '1964', 'Sean Connery', 'Guy Hamilton', '820.4', '18.6', '3.2']
可以發現輸出是以|
隔開的,那這就是register_dialect
的用法,用來變更分隔符號。
可以比較跟下面這個程式碼的差別(讀取同個檔案),可以看到輸出就沒有被分隔開來,因爲預設爲逗點(,)
:
with open('./myTextFile.csv','r') as f:
lines = csv.reader(f)
for i in lines:
print(i)
# ['Film|Year|Actor|Director|Box Office|Budget|Bond Actor Salary']
# ['Dr. No|1962|Sean Connery|Terence Young|448.8|7|0.6']
# ['From Russia with Love|1963|Sean Connery|Terence Young|543.8|12.6|1.6']
# ['Goldfinger|1964|Sean Connery|Guy Hamilton|820.4|18.6|3.2']
- 當然,在寫入時也可以增加參數
delimiter
,定義分隔的福號,像這樣:
writer = csv.writer(csvfile, delimiter=' ')
- 列出在目前
csv
中的所有delimiter
:
print (csv.list_dialects())
- 刪除
delimiter
unregister_dialect(name)
二、JSON使用
JSON (JavaScript Object Notation), specified by RFC 7159 (which obsoletes RFC 4627) and by ECMA-404, is a lightweight data interchange format inspired by JavaScript object literal syntax (although it is not a strict subset of JavaScript [1] ).
上面爲JSON
的介紹,總之JSON
是一種輕量級的數據交換格式也很好閱讀,就像是Python中的Dictionary
一樣。
其實json
套件,主要只有兩個函數要用,分別是:
json.dumps
: 用來將Python的資料類型編成JSON格式。json.loads
: 將JSON物件轉爲Python資料類型。
範例:
- 建立一個
dictionary
資料,裏面包含name, height, weight這三個Key的資料。 - 透過
dumps
將這個dic轉成JSON的字串。 - 將JSON字串轉回Python Dictionary格式。
import json
data = {
'name' : 'plusone''',
'height' : 155,
'weight' : 40
}
jsonStr = json.dumps(data, sort_keys=True, indent=1)
print(jsonStr)
data = json.loads(jsonStr)
print(data)
參數:
sort_keys
: 這個應該字面上很好理解了,是否排序Key。indent
: 若給非負整數,會幫你格式編排好看依照(填入的)數字等級。
可以比較兩者差異:
json_str = json.dumps(data, sort_keys=True, indent=5)
print(json_str)
# {
# "height": 155,
# "name": "plusone",
# "someStr": [
# {
# "a": 123,
# "b": 456
# }
# ]
# }
json_str = json.dumps(data, sort_keys=True, indent=1)
print(json_str)
# {
# "height": 155,
# "name": "plusone",
# "someStr": [
# {
# "a": 123,
# "b": 456
# }
# ]
# }
- 基本上
json
編碼對Python而言幾乎沒有改變包含None
,bool
,int
,float
,str
,list
,tuple
,dictionary
。
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
- 比較特別的是
true
/True
、false
/False
,而None
則會轉爲Null
,例如:
data = {
'one':True,
'two':False,
'three':None
}
json_str = json.dumps(data, indent=3)
print(json_str)
# output
# {
# "one": true,
# "three": null,
# "two": false
# }
接着要說明pprint()
這個套件。在loads()
後print()
出來會很難閱讀,這時候可以使用pprint()
:
from pprint import pprint
data = {
'one':True,
'two':False,
'three':
{
'text':[{'something': '2343488854324'},
{'something': '2343453454354'},
{'something': '1231242343545'},
{'something': '3423423432113'}]
}
}
# output
# {'one': True,
# 'three': {'text': [{'something': '2343488854324'},
# {'something': '2343453454354'},
# {'something': '1231242343545'},
# {'something': '3423423432113'}]},
# 'two': False}
若是用print()
:
# {'one': True, 'two': False, 'three': {'text': [{'something': '2343488854324'}, {'something': '2343453454354'}, {'something': '1231242343545'}, {'something': '3423423432113'}]}}
參考:
json — JSON encoder and decoder — Python 3.7.1rc1 documentation
pprint — Data pretty printer — Python 3.7.1rc1 documentation
三、pickle使用
1、pickle序列化
pickle.dump()方法將obj對象序列化爲字節(bytes)寫入到file文件中:
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
pickle.dumps()方法將obj對象序列化並返回一個bytes對象:
pickle.dumps(obj, protocol=None, *, fix_imports=True)
例:
import pickle
dict1 = dict(name='八岐大蛇',
age=1000,
sex='男',
addr='東方',
enemy=['八神', '草薙京', '神樂千鶴'])
print(dict1)
data_dumps = pickle.dumps(dict1)
print(data_dumps)
print(type(data_dumps)) # 返回的是bytes
data_file = open('dump.txt', 'wb')
pickle.dump(dict1, data_file)
data_file.close()
# 控制檯輸出
# 控制檯輸出
{'name': '八岐大蛇', 'age': 1000, 'sex': '男', 'addr': '東方', 'enemy': ['八神', '草薙京', '神樂千鶴']}
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x0c\x00\x00\x00\xe5\x85\xab\xe5\xb2\x90\xe5\xa4\xa7\xe8\x9b\x87q\x02X\x03\x00\x00\x00ageq\x03M\xe8\x03X\x03\x00\x00\x00sexq\x04X\x03\x00\x00\x00\xe7\x94\xb7q\x05X\x04\x00\x00\x00addrq\x06X\x06\x00\x00\x00\xe4\xb8\x9c\xe6\x96\xb9q\x07X\x05\x00\x00\x00enemyq\x08]q\t(X\x06\x00\x00\x00\xe5\x85\xab\xe7\xa5\x9eq\nX\t\x00\x00\x00\xe8\x8d\x89\xe8\x96\x99\xe4\xba\xacq\x0bX\x0c\x00\x00\x00\xe7\xa5\x9e\xe4\xb9\x90\xe5\x8d\x83\xe9\xb9\xa4q\x0ceu.'
<class 'bytes'>
Process finished with exit code 0
2、pickle反序列化
pickle.load() 從一個對象文件中讀取序列化數據,將其反序列化之後返回一個對象:
pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict")
pickle.loads() 將bytes反序列化並返回一個對象:
pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")
例:
data_loads = pickle.loads(data_dumps)
print(data_loads)
data_file = open('dump.txt', 'rb')
data_load = pickle.load(data_file)
print(data_load)
# 反序列化輸出:
{'name': '八岐大蛇', 'age': 1000, 'sex': '男', 'addr': '東方', 'enemy': ['八神', '草薙京', '神樂千鶴']}
{'name': '八岐大蛇', 'age': 1000, 'sex': '男', 'addr': '東方', 'enemy': ['八神', '草薙京', '神樂千鶴']}
Process finished with exit code 0
3、pickle與json的區別
pickle與json都可以實現序列化以及反序列化,它們之間不同的有以下幾點:
1)pickle不是用於多種語言間的數據傳輸,它僅作爲python對象的持久化,只針對python的數據類型;而json可以支持更多語言的序列化和反序列化,在python中序列化一個自定義的類對象時,會拋出一個 TypeError。
2)json的序列化輸出是文本對象是str類型,而pickle序列化的輸出是二進制字節-bytes。
3)json可讀性優於pickle。