△點選上方「Python貓」關注 ,回復「2」加入交流群
作者:Peter
來源:Python程式設計時光
在實際工作中,尤其是web資料的傳輸,我們經常會遇到json資料。它不像常見的文字資料、數值資料那樣友好,而且它和Python中的字典型別資料又很相像,給很多人造成了困擾。
本文結合具體範例詳細介紹了如何利用Python和pandas(Python的第三方庫)來處理json資料,主要內容包含:
-
json資料簡介
-
常用json資料轉化網站
-
json資料和Python資料的轉化
-
pandas處理json資料
1. JSON 簡單介紹
1.1 什麼是json資料
首先,我們看一段來自維基百科對json的解釋:
JSON(JavaScript Object Notation,JavaScript物件表示法)是一種由道格拉斯·克羅克福特構想和設計、輕量級的資料交換語言,該語言以易於讓人閱讀的文字為基礎,用來傳輸由屬性值或者序列性的值組成的資料物件。
JSON 資料格式與語言無關。即便它源自JavaScript,但目前很多程式設計語言都支援 JSON 格式資料的生成和解析。副檔名是
.json 。
透過上面的官方介紹,我們總結3點:
-
JSON是一種文字(資料)語言,超輕量級的資料交換格式
-
JSON資料容易閱讀,易讀性強
-
源自JavaScript,其他語言可解析JSON資料
1.2 json資料型態
JSON實際上是JavaScript的一個子集,JSON語言中僅有的6種資料型態或者它們之間的任意組合:
-
number:和JavaScript中的number一致
-
boolean:JavaScript中的true或者false
-
string:JavaScript中的string
-
null:JavaScript中的null
-
array:JavaScript的表示方式:[]
-
object:JavaScript的
{…} 表示方式
1.3 兩點規定
1、JSON語言中規定了編碼表必須是UTF-8
2、為了統一解析,JSON的字串規定必須是雙引號
2. 常用json資料轉化網站
1、json.cn:https://www.json.cn/
2、json菜鳥工具:https://c.runoob.com/front-end/53
3、sojson:https://www.sojson.com/,非常全的json處理網站
4、kjson:https://www.kjson.com/
5、程式設計獅-json檢驗工具:https://www.w3cschool.cn/tools/index?name=jsoncheck
6、JSONViewer:http://jsonviewer.stack.hu/,用於檢測Json格式是否正確的一個線上應用工具
3. JSON 和 Dict 型別轉化
本小節主要講解的json型別資料和Python型別的轉化。
首先使用的時候直接匯入該包:
1 | import json |
方法 | 作用 |
---|---|
json.dumps() | 將python物件編碼成Json字串:字典到json |
json.loads() | 將Json字串解碼成python物件:json到字典 |
json.dump() | 將python中的物件轉化成json儲存到檔案中 |
json.load() | 將檔案中的json的格式轉化成python物件選取出來 |
筆記:兩個和load相關的方法只是多了一步和檔案相關的操作。
json.dumps
和dump相關的兩個函式是將Python資料型態轉成json型別,轉化對照表如下:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
1 2 3 4 5 6 7 8 9 10 11 12 | json.dumps(obj, # 待轉化的物件 skipkeys=False, # 預設值是False,若dict的keys內的資料不是python的基本型別(str,unicode,int,long,float,bool,None),設定為False時,就會報TypeError的錯誤。此時設定成True,則會跳過這類key ensure_ascii=True, # 預設是ASCII碼,若設定成False,則可以輸出中文 check_circular=True, # 若為False,跳過對容器型別的迴圈引用檢查 allow_nan=True, # 若allow_nan為假,則ValueError將序列化超出範圍的浮點值(nan、inf、-inf),嚴格遵守JSON規範,而不是使用JavaScript等效值(nan、Infinity、-Infinity) cls=None, indent=None, # 引數根據格式縮進顯示,表示縮進幾個空白 separators=None, # 指定分隔符;包含不同dict項之間的分隔符和key與value之間的分隔符;同時去掉`: ` encoding="utf-8", # 編碼 default=None, # 預設是一個函式,應該回傳可序列化的obj版本或者引髮型別錯誤;預設值是只引髮型別錯誤 sort_keys=False, # 若為False,則字典的鍵不排序;設定成True,按照字典排序(a到z) **kw) |
透過範例來解釋上面幾個常見引數的作用
1、當我們的Python型別資料中存在中文
1 2 3 4 5 6 7 8 9 10 11 | information1 = { 'name': '小明', 'age': 18, 'address': 'shenzhen' } # 字典轉成json資料 information2 = json.dumps(information1) print(type(information1)) print(type(information2)) print(information2) |
加上
1 2 | # 字典轉成json資料 information3 = json.dumps(information1,ensure_ascii=False) |
??透過結果我們發現:json資料中全部變成了雙引號,原來的字典型別資料中使用的是單引號,再看一個關於引號變化的範例:
1 2 3 4 5 6 7 8 | >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) # python中的鍵是字串,用單引號 # 結果顯示 { "4": 5, # 變成雙引號 "6": 7 } |
2、對json資料透過縮進符美觀輸出,使用indent引數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | information4 = { 'name': '小明', 'age': 18, 'skills': 'python', 'english': 'CET6', 'major': '會計', 'address': '深圳' } information5 = json.dumps(information4, ensure_ascii=False) # 不縮進 information6 = json.dumps(information4, ensure_ascii=False, indent=2) # 縮進2個空白 information7 = json.dumps(information4, ensure_ascii=False, indent=5) # 縮進5個空白 print(information5) print(information6) print(information7) |
3、對Python資料型態中鍵進行排序輸出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | information4 = { 'name': '小明', 'age': 18, 'skills': 'python', 'english': 'CET6', 'major': '會計', 'address': '深圳' } information8 = json.dumps(information4, ensure_ascii=False, indent=2) # information9 = json.dumps(information4, ensure_ascii=False, indent=2,sort_keys=True) # 鍵的排序設定成True print(information8) print(information9) |
透過
4、輸出分隔符的控制
使用
1 2 3 4 5 6 7 8 9 10 11 | information1 = { 'name': '小明', 'age': 18, 'address': 'shenzhen' } information2 = json.dumps(information1,ensure_ascii=False) information10 = json.dumps(information1,ensure_ascii=False,separators=('+','@')) # 改變分隔符 print(information2) # 預設連接符 print(information10) |
json.dump
我們嘗試將下面的個人訊息寫入到檔案中
1 2 3 4 5 6 7 8 | information = { 'name': '小明', 'age': 18, 'skills': 'python', 'english': 'CET6', 'major': '會計', 'address': '深圳' } |
1、如果不使用
1 2 3 4 5 6 7 8 | # 使用json.dump;json資料一定是雙引號 with open("information_1_to_json.json", "w", encoding='utf-8') as f: # json.dump(dic_, f) # 全部寫入一行資料,不換行 json.dump(information, # 待寫入資料 f, # File物件 sort_keys=True, # 鍵的排序 ensure_ascii=False) # 顯示中文 |
看看實際的儲存效果:
加入
1 2 3 4 5 6 | with open("information_2_to_json.json", "w", encoding='utf-8') as f: json.dump(information, f, indent=2, # 空白縮進符,寫入多行 sort_keys=True, ensure_ascii=False) |
json.loads
和
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number (real) | float |
true | True |
false | False |
null | None |
1 2 3 4 5 6 7 8 9 10 | information1 = { 'name': '小明', 'age': 18, 'address': 'shenzhen' } # 字典轉成json資料 information3 = json.dumps(information1,ensure_ascii=False) information11 = json.loads(information3) # json轉成字典資料 print(information11) |
json.load
開啟json檔案再轉成字典形式的資料
1 2 3 4 5 6 | # 使用json.load with open("information_to_json.json",encoding="utf-8") as f: json_to_dict = json.load(f) # json轉成字典 print(json_to_dict) |
4. JSON 和 非 Dict 型別的轉化
上面介紹的主要是json格式資料和Python字典之間的轉化,下面講解了Python其他資料型態透過
1、元組轉化
2、串列轉化
3、布林值轉化
4、數值型資料轉化
5. 利用 Demjson 來解析
-
encode:將 Python 物件編碼成 JSON 字串
-
decode:將已編碼的 JSON 字串解碼為 Python 物件
安裝demjson
直接使用
使用demjson
使用之前先進行匯入:
1 | import demjson # 匯入包 |
1、編碼功能
2、解碼功能
如果我們想看到中文資料,可以使用eval函式:
6. Pandas處理 json
下面介紹pandas庫對json資料的處理:
-
read_json:從json檔案中讀取資料
-
to_json:將pandas中的資料寫入到json檔案中
-
json_normalize:對json資料進行規範化處理
https://geek-docs.com/pandas/pandas-read-write/pandas-reading-and-writing-json.html
6.1 read_json
首先看看官網中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | pandas.read_json( path_or_buf=None, # json檔案路徑 orient=None, # 重點引數,取值為:"split"、"records"、"index"、"columns"、"values" typ='frame', # 要恢復的物件型別(系列或框架),預設』框架』. dtype=None, # boolean或dict,預設為True convert_axes=None, convert_dates=True, keep_default_dates=True, numpy=False, precise_float=False, date_unit=None, encoding=None, lines=False, # 布林值,預設為False,每行讀取該檔案作為json物件 chunksize=None, compression='infer', nrows=None, storage_options=None) |
詳細的引數解析可以參考文章:https://blog.csdn.net/qq_41562377/article/details/90203805
假設我們現在有一份json資料,如下圖所示:
我們將上面的資料讀取進來,由於資料是比較規範的,所以直接填寫檔案路徑即可讀取:
重點講解下引數
1、oriden='split'
1 | split』 : dict like {index -> [index], columns -> [columns], data -> [values]} |
json檔案的key的名字只能為
2、orient='records'
1 | 『records』 : list like [{column -> value}, … , {column -> value}] |
3、orient='index'
1 | dict like {index -> {column -> value}} |
4、orient='columns'
1 | dict like {column -> {index -> value}} |
轉置之後就是上面
5、orient='values'
1 | 『values』 : just the values array |
6.2 to_json
1 | df.to_json("個人訊息.json") # 直接儲存成json檔案 |
如果按照上面的程式碼儲存,中文是沒有顯示的:
當然我們可以透過
1 | df.to_json("個人訊息1.json",force_ascii=False) # 顯示中文 |
6.3 json_normalize
https://www.jianshu.com/p/a84772b994a0
上面介紹的json資料的儲存和讀取中json資料都是串列形式的;但是json檔案中的資料通常不一定全部是串列形式,那麼我們需要將字典結構的檔案轉成串列形式,這個過程就叫做規範化。
pandas中的
1 | from pandas.io.json import json_normalize |
透過官網和一個實際的範例來同時進行學習,首先看看官網的範例:
1、層級字典透過屬性的形式顯示資料:
2、如果加入max_level引數則會顯示不同的效果:
若max_level=0,則巢狀的字典會當做整體,顯示在資料框中
若max_level=1,則巢狀的字典會被拆解,裡面的鍵會被單獨出來:
3、讀取層級巢狀中的部分內容:
4、讀取全部內容
7. 總結一下
本文首先對
希望這篇文章的詳細講解,能夠幫助到各位搞定
近兩年里,我原創和翻譯了130+技術文章,主要關注Python進階、小技巧、程式設計設計、PEP翻譯、Python哲學等話題。現已集結出了一本電子書《優雅的Python》,請回復數值『1』,取得下載地址。
近期熱門文章推薦:
好的程式設計語言具備哪些屬性?
深入理解Python的TLS機制和Threading.local()
Python 為什麼用 # 號作註解符?
耗時兩年,我終於出了一本電子書!
Linux 日誌切割神器 Logrotate 原理和配置詳解(附多生產例項)
分享與在看是對我最大的支援!