Python數據處理(一):處理 JSON、XML、CSV 三種格式數據

Python 數據處理系列博客來啦!php

本系列將以《Python數據處理》這本書爲基礎,以書中每章一篇博客的形式帶你們一塊兒學習 Python 數據處理。書中有些地方講的不太詳細,我會查閱其餘資料來補充,力爭每篇博客都把知識點涵蓋全且通俗易懂。python

這本書主要講了如何用 Python 處理各類類型的文件,如 JSON、XML、CSV、Excel、PDF 等。後面幾章還會講數據清洗、網頁抓取、自動化和規模化等使用技能。我也是 Python 初學者,將以初學者的角度寫文章,因此博客對初學者比較友好。git

python 基礎若是你還不熟練,能夠先看看個人另外一篇博客:十分鐘快速入門 Python程序員

100 多位經驗豐富的開發者參與,在 Github 上得到了近 1000star 的全棧全平臺開源項目想了解或參與嗎?
項目地址:github.com/cachecats/c…github

前言

以易於機器理解的方式來存儲數據的文件格式,一般被稱做機器可讀的 (machine readable)。常見的機器可讀格式包括:json

  • 逗號分隔值(Comma-Separated Values,CSV)
  • JavaScript 對象符號(JavaScript Object Notation,JSON)
  • 可擴展標記語言(eXtensible Markup Language,XML)

在口語和書面語中,提到這些數據格式時一般使用它們的短名字(如 CSV)。 咱們將使用這些縮寫 。小程序

1、CSV數據

CSV 文件(簡稱爲 CSV)是指將數據列用逗號分隔的文件。文件的擴展名是 .csv。bash

另外一種數據類型,叫做製表符分隔值(tab-separated values,TSV)數據,有時也與 CSV歸爲一類。TSV 與 CSV 惟一的不一樣之處在於,數據列之間的分隔符是製表符(tab),而不是逗號。文件的擴展名一般是 .tsv,但有時也用 .csv 做爲擴展名。從本質上來看,.tsv 文件與 .csv 文件在Python 中的做用是相同的。架構

咱們採用的數據源是從世界衛生組織(www.who.int/zh/home)中下載…app

打開世衛組織官網後,點擊「健康主題」,「數據和統計」 就能找到不少數據。

這裏下載了關於嬰幼兒護理的統計數據,並重命名爲 data.csv

csv 文件能夠直接用 Excel 打開直觀的看到,咱們用 Excel 打開以下圖:

接下來就要用 Python 來簡單的處理這些數據。

以列表的形式讀取csv數據

編寫一個讀取 csv 文件的程序:

import csv

csvfile = open('./data.csv', 'r')
reader = csv.reader(csvfile)

for row in reader:
    print(row)
複製代碼

import csv 將導入 Python 自帶的 csv 模塊。csvfile = open('./data.csv', 'r') 以只讀的形式打開數據文件並存儲到變量 csvfile 中。而後調用 csv 的 reader() 方法將輸出保存在 reader 變量中,再用 for 循環將數據輸出。

運行程序,控制檯輸出:

能夠看到跟 Excel 打開的內容一致。

以字典的形式讀取csv數據

改一下代碼,以字典的形式讀取 csv

import csv

csvfile = open('./data.csv', 'r')
reader = csv.DictReader(csvfile)

for row in reader:
    print(row)
複製代碼

控制檯輸出:

2、JSON數據

一樣在世衛組織官網下載數據源,重命名爲 data.json。用格式化工具打開 json 文件以下:

編寫程序對 json 進行解析

import json

# 將 json 文件讀取成字符串
json_data = open('./data.json').read()
# 對json數據解碼
data = json.loads(json_data)
# data 的類型是 字典dict
print(type(data))
# 直接打印 data
print(data)
# 遍歷字典
for k, v in data.items():
    print(k + ':' + str(v))
複製代碼

控制檯輸出:

Python3 中可使用 json 模塊來對 JSON 數據進行編解碼,它包含了兩個函數:

  • json.dumps(): 對數據進行編碼。
  • json.loads(): 對數據進行解碼。

在json的編解碼過程當中,python 的原始類型與json類型會相互轉換,具體的轉化對照以下:

Python 編碼爲 JSON 類型轉換對應表:

Python JSON
dict object
list, tuple array
str string
int, float, int- & float-derived Enums number
True true
False false
None null

JSON 解碼爲 Python 類型轉換對應表:

JSON Python
object dict
array list
string str
number (int) int
number (real) float
true True
false False
null None

3、XML 數據

XML 格式的數據既便於機器讀取,也便於人工讀取。可是對於本章的數據集來講,預覽並理解 CSV 文件和 JSON 文件要比 XML 文件容易得多。

xml 格式說明:

  • Tag: 使用<和>包圍的部分;
  • Element:被Tag包圍的部分,如 2003,能夠認爲是一個節點,它能夠有子節點;
  • Attribute:在Tag中可能存在的 name/value 對,如示例中的 title="Enemy Behind",通常表示屬性。

世衛組織的數據很差理解,我們用個簡單的能看得懂的電影數據來作演示:

<?xml version="1.0" encoding="UTF-8"?>
<collection shelf="New Arrivals">
    <movie title="Enemy Behind">
        <type>War, Thriller</type>
        <format>DVD</format>
        <year>2003</year>
        <rating>PG</rating>
        <stars>10</stars>
        <description>Talk about a US-Japan war</description>
    </movie>
    <movie title="Transformers">
        <type>Anime, Science Fiction</type>
        <format>DVD</format>
        <year>1989</year>
        <rating>R</rating>
        <stars>8</stars>
        <description>A schientific fiction</description>
    </movie>
    <movie title="Trigun">
        <type>Anime, Action</type>
        <format>DVD</format>
        <episodes>4</episodes>
        <rating>PG</rating>
        <stars>10</stars>
        <description>Vash the Stampede!</description>
    </movie>
    <movie title="Ishtar">
        <type>Comedy</type>
        <format>VHS</format>
        <rating>PG</rating>
        <stars>2</stars>
        <description>Viewable boredom</description>
    </movie>
</collection>
複製代碼

這個數據相對來講比較簡單,只有三層。但原理掌握了,幾層數據都能搞定。

下面編寫代碼對上面的 xml 進行解析,解析以後再分別格式化成字典和 json 格式的數據輸出:

from xml.etree import ElementTree as ET
import json

tree = ET.parse('./resource/movie.xml')
root = tree.getroot()

all_data = []

for movie in root:
    # 存儲電影數據的字典
    movie_data = {}
    # 存儲屬性的字典
    attr_data = {}

    # 取出 type 標籤的值
    movie_type = movie.find('type')
    attr_data['type'] = movie_type.text

    # 取出 format 標籤的值
    movie_format = movie.find('format')
    attr_data['format'] = movie_format.text

    # 取出 year 標籤的值
    movie_year = movie.find('year')
    if movie_year:
        attr_data['year'] = movie_year.text

    # 取出 rating 標籤的值
    movie_rating = movie.find('rating')
    attr_data['rating'] = movie_rating.text

    # 取出 stars 標籤的值
    movie_stars = movie.find('stars')
    attr_data['stars'] = movie_stars.text

    # 取出 description 標籤的值
    movie_description = movie.find('description')
    attr_data['description'] = movie_description.text

    # 獲取電影名字,以電影名爲字典的鍵,屬性信息爲字典的值
    movie_title = movie.attrib.get('title')
    movie_data[movie_title] = attr_data
    # 存入列表中
    all_data.append(movie_data)

print(all_data)
# all_data 此時是一個列表對象,用 json.dumps() 將python對象轉換爲 json 字符串
json_str = json.dumps(all_data)
print(json_str)
複製代碼

註釋寫的比較詳細,下面介紹下 ElementTree 提供的方法。

3.1 解析的三種方法

ElementTree 解析 xml 有三種方法:

  1. 調用parse()方法,返回解析樹

    tree = ET.parse('./resource/movie.xml')
    root = tree.getroot()
    複製代碼
  2. 調用from_string(),返回解析樹的根元素

    data = open('./resource/movie.xml').read()
    root = ET.fromstring(data)
    複製代碼
  3. 調用 ElementTree 類的 ElementTree(self, element=None, file=None) 方法

    tree = ET.ElementTree(file="./resource/movie.xml")
    root = tree.getroot() 
    複製代碼

3.2 Element 對象

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

Element 對象的屬性

  • tag: 標籤
  • text: 去除標籤,得到標籤中的內容。
  • attrib: 獲取標籤中的屬性和屬性值。
  • tail: 這個屬性能夠用來保存與元素相關聯的附加數據。它的值一般是字符串,但多是特定於應用程序的對象。

Element 對象的方法

  1. clear():清除全部子元素和全部屬性,並將文本和尾部屬性設置爲None。

  2. get(attribute_name, default=None):經過指定屬性名獲取屬性值。

  3. items():以鍵值對的形式返回元素屬性。

  4. keys():以列表的方式返回元素名。

  5. set(attribute_name,attribute_value):在某標籤中設置屬性和屬性值。

  6. append(subelement):將元素子元素添加到元素的子元素內部列表的末尾。

  7. extend(subelements):追加子元素。

  8. find(match, namespaces=None):找到第一個匹配的子元素,match能夠是標籤名或者path。返回Elememt實例或None。

  9. findall(match, namespaces=None):找到全部匹配的子元素,返回的是一個元素列表。

  10. findtext(match, default=None, namespaces=None):找到匹配第一個子元素的文本。返回的是匹配元素中的文本內容。

  11. getchildren():Python3.2後使用 list(elem) 或 iteration.

  12. getiterator(tag=None):Python3.2後使用 Element.iter()

  13. iter(tag=None):以當前元素爲根建立樹迭代器。迭代器遍歷這個元素和它下面的全部元素(深度優先級)。若是標籤不是None或’*’,那麼只有標籤等於標籤的元素纔會從迭代器返回。若是在迭代過程當中修改樹結構,則結果是未定義的。

  14. iterfind(match, namespaces=None): 匹配知足條件的子元素,返回元素。

3.3 ElementTree 對象

class xml.etree.ElementTree.ElementTree(element=None, file=None)

ElementTree是一個包裝器類,這個類表示一個完整的元素層次結構,併爲標準XML的序列化添加了一些額外的支持。

  1. setroot(element):替換根元素,原來的根元素中的內容會消失。

  2. find(match, namespaces=None):從根元素開始匹配和 Element.find()做用同樣。

  3. findall(match, namespaces=None):從根元素開始匹配和 Element.findall()做用同樣。

  4. findtext(match, default=None, namespaces=None):從根元素開始匹配和 Element.findtext()做用同樣。

  5. getiterator(tag=None):Python3.2後使用 ElementTree.iter() 代替。

  6. iter(tag=None):迭代全部元素

  7. iterfind(match, namespaces=None):從根元素開始匹配和 Element.iterfind()做用同樣。

  8. parse(source, parser=None):解析xml文本,返回根元素。

  9. write(file, encoding=」us-ascii」, xml_declaration=None, default_namespace=None, method=」xml」, *, short_empty_elements=True):寫出XML文本。

對 JSON、XML、CSV三種格式數據的處理就講完啦,下期講如何處理 Excel 文件,歡迎關注。


全棧全平臺開源項目 CodeRiver

CodeRiver 是一個免費的項目協做平臺,願景是打通 IT 產業上下游,不管你是產品經理、設計師、程序員或是測試,仍是其餘行業人員,只要有好的創意、想法,均可以來 CodeRiver 免費發佈項目,召集志同道合的隊友一塊兒將夢想變爲現實!

CodeRiver 自己仍是一個大型開源項目,致力於打造全棧全平臺企業級精品開源項目。涵蓋了 React、Vue、Angular、小程序、ReactNative、Android、Flutter、Java、Node 等幾乎全部主流技術棧,主打代碼質量。

目前已經有近 100 名優秀開發者參與,github 上的 star 數量將近 1000 個。每一個技術棧都有多位經驗豐富的大佬坐鎮,更有兩位架構師指導項目架構。不管你想學什麼語言處於什麼技術水平,相信都能在這裏學有所獲。

經過 高質量源碼 + 博客 + 視頻,幫助每一位開發者快速成長。

項目地址:github.com/cachecats/c…


您的鼓勵是咱們前行最大的動力,歡迎點贊,歡迎送小星星✨ ~

相關文章
相關標籤/搜索