[python] 基于Tablib库处理表格数据
Tablib是一個(gè)用于處理電子表格(如 Excel,CSV,JSON)的Python 庫(kù)。它提供了一種簡(jiǎn)單而強(qiáng)大的方式來(lái)操作和處理數(shù)據(jù)。利用Tablib,我們可以輕松地讀取、寫入、過(guò)濾和轉(zhuǎn)換各種類型的電子表格數(shù)據(jù)。Tablib 具有一致且易于使用的 API,以在不同的數(shù)據(jù)格式之間進(jìn)行無(wú)縫轉(zhuǎn)換。比如,Tablib可以將數(shù)據(jù)從Excel表格導(dǎo)入為Python對(duì)象,然后將其轉(zhuǎn)換為JSON或CSV格式,并進(jìn)行相應(yīng)的操作和分析。此外Tablib還支持對(duì)數(shù)據(jù)進(jìn)行排序、篩選和合并等常見(jiàn)操作。Tablib官方倉(cāng)庫(kù)地址為:tablib,Tablib官方文檔地址為:tablib-doc。
Tablib需要在Python3.6+版本下安裝,安裝命令如下:
pip install tablib
import tablib
# 查看版本
tablib.__version__
'3.4.0'
目錄
-
1 Tablib使用
- 1.1 表格創(chuàng)建
- 1.2 數(shù)據(jù)導(dǎo)入與導(dǎo)出
- 1.3 多表管理
- 1.4 進(jìn)階使用
- 2 參考
1 Tablib使用
1.1 表格創(chuàng)建
創(chuàng)建數(shù)據(jù)結(jié)構(gòu)
# 創(chuàng)建表
data = tablib.Dataset()
type(data)
tablib.core.Dataset
# 查看表格名字,默認(rèn)為空
data.title
# 設(shè)置表的名字
data.title = 'data'
data.title
'data'
數(shù)據(jù)添加
# 添加行
data.append(['John', 28])
data.append(['Tom', 16])
data.append(['Jane', 32])
# 查看數(shù)據(jù),list格式
data.dict
# 或者
# print(data)
[['John', 28], ['Tom', 16], ['Jane', 32]]
# 添加標(biāo)題行
data.headers = ['Name', 'Age']
# data.dict
print(data)
Name|Age
----|---
John|28
Tom |16
Jane|32
# 添加列
# 需要和當(dāng)前行數(shù)一致
data.append_col(['USA', 'UK','UK'], header='Country')
# data.dict
print(data)
Name|Age|Country
----|---|-------
John|28 |USA
Tom |16 |UK
Jane|32 |UK
選擇行或列
# 選擇第一行
data[0]
('John', 28, 'USA')
# 選擇第一行第三列
data[0][2]
'USA'
# 選擇列
data['Age']
[28, 16, 32]
# 獲得表頭
data.headers
['Name', 'Age', 'Country']
# 基于索引獲得列
data.get_col(0)
['John', 'Tom', 'Jane']
刪除行或列
# 刪除列
del data['Country']
# 刪除行
# del data[:-1]
print(data)
Name|Age
----|---
John|28
Tom |16
Jane|32
行列高級(jí)操作
# 表格轉(zhuǎn)置
transposed_data = data.transpose()
print(transposed_data)
Name|John|Tom|Jane
----|----|---|----
Age |28 |16 |32
# 讀取數(shù)據(jù)維度
data.width,data.height
(2, 3)
# 按照字段排序
# 年齡從大到小排序
data = data.sort("Age",reverse=True)
print(data)
Name|Age
----|---
Jane|32
John|28
Tom |16
# 計(jì)算平均年齡
ages = data['Age']
float(sum(ages)) / len(ages)
25.333333333333332
# 移除第一行
tmp = data.lpop()
print(data)
Name|Age
----|---
John|28
Tom |16
# 第一行添加數(shù)據(jù)
data.lpush(list(tmp))
print(data)
Name|Age
----|---
Jane|32
John|28
Tom |16
# 在最左側(cè)插入一列數(shù)據(jù)
new_column = ['Engineer', 'Doctor','Doctor']
data.lpush_col(new_column, header='Profession')
print(data)
Profession|Name|Age
----------|----|---
Engineer |Jane|32
Doctor |John|28
Doctor |Tom |16
# 移除最后一行
# data.pop()
# print(data)
# 移除重復(fù)行
# 創(chuàng)建數(shù)據(jù)集
data = tablib.Dataset()
data.headers = ['Name', 'Age']
data.append(['Alice', 25])
data.append(['Alice', 30])
data.append(['Alice', 25]) # 重復(fù)行
# 去除重復(fù)行,必須所有列值一樣
data.remove_duplicates()
print(data)
Name |Age
-----|---
Alice|25
Alice|30
表格合并
# 創(chuàng)建兩個(gè)表格
data1 = tablib.Dataset()
data1.headers = ['Name', 'Age']
data1.append(['Alice', 25])
data1.append(['Bob', 30])
data2 = tablib.Dataset()
data2.headers = ['Name', 'Occupation']
data2.append(['Alice', 'Engineer'])
data2.append(['Bob', 'Doctor'])
# 按行合并
# 使用stack方法合并兩個(gè)表格
stacked_data = data1.stack(data2)
print(stacked_data)
Name |Age
-----|--------
Alice|25
Bob |30
Alice|Engineer
Bob |Doctor
# 按列合并
# 兩個(gè)表格行數(shù)需要一致
# 使用stack_cols方法合并兩個(gè)表格的列
stacked_cols_data = data1.stack_cols(data2)
print(stacked_cols_data)
Name |Age|Name |Occupation
-----|---|-----|----------
Alice|25 |Alice|Engineer
Bob |30 |Bob |Doctor
1.2 數(shù)據(jù)導(dǎo)入與導(dǎo)出
數(shù)據(jù)導(dǎo)出
Tablib使得用戶可以根據(jù)具體需求將數(shù)據(jù)靈活地導(dǎo)出到不同的環(huán)境中,并與其他工具進(jìn)行無(wú)縫集成和交互。轉(zhuǎn)換的結(jié)果是這些格式的對(duì)象表示而不是存為本地文件。這些格式包括但不限于:
- CSV:常見(jiàn)的電子表格格式,每個(gè)字段由逗號(hào)分隔。
- JSON:一種常見(jiàn)的數(shù)據(jù)交換格式,以鍵值對(duì)的形式存儲(chǔ)數(shù)據(jù)。
- Excel:電子表格格式,需要額外安裝庫(kù),可以包含多個(gè)工作表,并支持公式和圖表等功能。
- YAML:一種易讀的數(shù)據(jù)序列化格式,常用于配置文件。
- HTML:用于創(chuàng)建網(wǎng)頁(yè)的標(biāo)記語(yǔ)言。
- Pandas DataFrame:Pandas是另一個(gè)Python庫(kù),用于數(shù)據(jù)處理和分析。Tablib支持將數(shù)據(jù)導(dǎo)出為Pandas DataFrame。
Tablib提供了兩種方式將數(shù)據(jù)導(dǎo)出為其他格式,一種是調(diào)用export函數(shù),一種是調(diào)用自帶屬性。如下所示data.export('csv') 和data.csv都可以用于獲取Dataset數(shù)據(jù)的CSV表示:
data.export('csv')
data.csv
具體示例代碼如下:
# 創(chuàng)建表格
data = tablib.Dataset()
data.headers = ['Name', 'Age']
data.append(['John', 28])
data.append(['Tom', 16])
data.append(['Jane', 32])
# 導(dǎo)出為csv字符流
data_csv = data.export('csv')
print(type(data_csv))
# 導(dǎo)出數(shù)據(jù)到本地csv文件
with open('data.csv', 'w') as f:
f.write(data_csv)
<class 'str'>
# 導(dǎo)出為json字符串
data_json = data.export('json')
type(data_json)
# 將json字符串解析為Python對(duì)象
import json
data_json = json.loads(data_json)
print(data_json)
[{'Name': 'John', 'Age': 28}, {'Name': 'Tom', 'Age': 16}, {'Name': 'Jane', 'Age': 32}]
# 將數(shù)據(jù)集對(duì)象保存為json文件
with open('data.json', 'w') as f:
f.write(data.export('json'))
# 保存為yaml文件
with open('data.yml', 'w') as f:
f.write(data.export('yaml'))
# 將數(shù)據(jù)集保存為xls文件,注意使用wb模式
# 需要安裝額外庫(kù)
# pip install xlrd
# pip install xlwt
with open('data.xls', 'wb') as f:
f.write(data.export('xls'))
with open('data.xlsx', 'wb') as f:
f.write(data.export('xlsx'))
# 轉(zhuǎn)換為html
# 需要安裝MarkupPy庫(kù)
# pip install MarkupPy
with open('data.html', 'w') as f:
f.write(data.export('html'))
# 轉(zhuǎn)換為pandas的dataframe
# 需要安裝Pandas庫(kù)
df = data.export('df')
df.head()
| Name | Age | |
|---|---|---|
| 0 | John | 28 |
| 1 | Tom | 16 |
| 2 | Jane | 32 |
數(shù)據(jù)導(dǎo)入
我們可以使用tablib庫(kù)導(dǎo)入多種格式的文件,以初始化tablib的數(shù)據(jù)對(duì)象。如下所示:
with open('data.csv', 'r') as fh:
imported_data = tablib.Dataset().load(fh)
print(imported_data)
Name|Age
----|---
John|28
Tom |16
Jane|32
對(duì)于表格類格式,如csv格式,也可以不導(dǎo)入標(biāo)題行,即不將第一行作為標(biāo)題行,如下所示:
with open('data.csv', 'r') as fh:
# headers=False不導(dǎo)入標(biāo)題行
imported_data = tablib.Dataset().load(fh,headers=False)
print(imported_data)
Name|Age
John|28
Tom |16
Jane|32
對(duì)于支持多表的xls、xlsx,當(dāng)前默認(rèn)打開第一個(gè)表,注意使用rb模式。多表管理見(jiàn)下一節(jié)。
with open('data.xls', 'rb') as fh:
imported_data = tablib.Dataset().load(fh, 'xls')
print(imported_data)
Name|Age
----|----
John|28.0
Tom |16.0
Jane|32.0
1.3 多表管理
在Tablib中,Databook是一種數(shù)據(jù)結(jié)構(gòu),用于組織和管理多個(gè)數(shù)據(jù)表(Data Table。Databook提供了一種方便的方式來(lái)操作和處理多個(gè)數(shù)據(jù)表
創(chuàng)建Databook
# 創(chuàng)建Databook
databook = tablib.Databook()
# 創(chuàng)建第一個(gè)數(shù)據(jù)表
data_table1 = tablib.Dataset()
# 設(shè)置數(shù)據(jù)表的列和數(shù)據(jù)
data_table1.headers = ['Name', 'Age']
data_table1.append(['John', 25])
data_table1.append(['Alice', 30])
# 設(shè)置表名
data_table1.title = "table1"
# 添加數(shù)據(jù)表到 Databook
databook.add_sheet(data_table1)
# 創(chuàng)建二個(gè)數(shù)據(jù)表
data_table2 = tablib.Dataset()
# 設(shè)置數(shù)據(jù)表的列和數(shù)據(jù)
data_table2.headers = ['Name', 'Age']
data_table2.append(['Jane', 34])
data_table2.append(['Mike', 14])
# 設(shè)置表名
data_table2.title = "table2"
# 添加數(shù)據(jù)表到 Databook
databook.add_sheet(data_table2)
# 可以利用現(xiàn)有表一次性創(chuàng)建Databoook
tablib.Databook((data_table1, data_table2))
<databook object>
查看databook
# 查看子表數(shù)量
databook.size
2
# 查看各表
databook.sheets()
[<table1 dataset>, <table2 dataset>]
根據(jù)索引獲得表
for index,table in enumerate(databook.sheets()):
print(f" \ntable{index}")
print(table)
table0
Name |Age
-----|---
John |25
Alice|30
table1
Name|Age
----|---
Jane|34
Mike|14
保存與導(dǎo)入
databook支持保存xlsx和xls文件,但是導(dǎo)入僅支持xlsx文件。
# 保存為xlsx文件
with open('databook.xlsx', 'wb') as f:
f.write(databook.export('xlsx'))
# 多表導(dǎo)入
with open(r'databook.xlsx', 'rb') as fh:
databook = tablib.Databook().load(fh, 'xlsx')
print(databook.sheets())
[<table1 dataset>, <table2 dataset>]
1.4 進(jìn)階使用
動(dòng)態(tài)列
Talblib允許在數(shù)據(jù)表格中隨意創(chuàng)建和管理動(dòng)態(tài)列。這些列不需要預(yù)先定義,可以根據(jù)需要隨時(shí)添加、刪除和修改。如下所示根據(jù)隨機(jī)函數(shù)設(shè)置列:
# 導(dǎo)入數(shù)據(jù)
with open('data.csv', 'r') as fh:
data = tablib.Dataset().load(fh)
print(data)
Name|Age
----|---
John|28
Tom |16
Jane|32
import random
# 隨機(jī)設(shè)置分?jǐn)?shù)
def random_grade(row):
# 根據(jù)傳入的行設(shè)置不同數(shù)據(jù)標(biāo)準(zhǔn)
if int(row[1]) > 30:
return (random.randint(59,100)/100.0)
else:
return (random.randint(60,99)/100.0)
data.append_col(random_grade, header='Grade')
print(data)
Name|Age|Grade
----|---|-----
John|28 |0.65
Tom |16 |0.99
Jane|32 |0.79
數(shù)據(jù)過(guò)濾
Tablib提供了filter方法,以根據(jù)數(shù)據(jù)集的標(biāo)簽(tags)來(lái)過(guò)濾數(shù)據(jù)。
fruits = tablib.Dataset()
fruits.headers = ['name', 'color']
# 添加tags為fruit與sour的行
fruits.append(['tomato', 'red'], tags=['fruit', 'sour'])
fruits.append(['strawberry', 'red'], tags=['fruit', 'sweet' ])
fruits.append(['corn', 'yellow'], tags=['vegetable', 'sweet'])
# 轉(zhuǎn)換為其他格式,tags屬性不會(huì)跟隨轉(zhuǎn)換
print(fruits.yaml)
- {color: red, name: tomato}
- {color: red, name: strawberry}
- {color: yellow, name: corn}
# 過(guò)濾出標(biāo)簽為vegetable的數(shù)據(jù)
fruits.filter(['vegetable']).df
| name | color | |
|---|---|---|
| 0 | corn | yellow |
# 過(guò)濾出標(biāo)簽為vegetable或sweet的數(shù)據(jù)
fruits.filter(['vegetable', 'sweet']).df
| name | color | |
|---|---|---|
| 0 | strawberry | red |
| 1 | corn | yellow |
# 先過(guò)濾出標(biāo)簽為fruit,再過(guò)濾為sour的數(shù)據(jù)
fruits.filter(['fruit']).filter(['sour']).df
| name | color | |
|---|---|---|
| 0 | tomato | red |
分割符
Tablib提供了append_separator函數(shù),以在excel表格中添加分隔符,如下所示:
# Daniel和Suzie的測(cè)試數(shù)據(jù)
daniel_tests = [
('11/24/09', 'Apple', 'Red'),
('05/24/10', 'Banana', 'Yellow')
]
suzie_tests = [
('11/24/09', 'Orange', 'Orange'),
('05/24/10', 'Grapes', 'Purple')
]
# 創(chuàng)建新的數(shù)據(jù)集
tests = tablib.Dataset()
tests.headers = ['Date', 'Fruit Name', 'Color']
# 添加分隔符
tests.append_separator('Fruits A')
for test_row in daniel_tests:
tests.append(test_row)
# 添加分隔符
tests.append_separator('')
for test_row in suzie_tests:
tests.append(test_row)
# 將數(shù)據(jù)集寫入磁盤,以xls格式存儲(chǔ)
with open('fruits.xls', 'wb') as f:
f.write(tests.export('xls'))
通過(guò)展示xls數(shù)據(jù),可以看到在某些行添加了空行數(shù)據(jù)。
# 導(dǎo)入pandas庫(kù)
import pandas as pd
# 從xls文件中讀取數(shù)據(jù),并將其存儲(chǔ)在DataFrame中
pd.read_excel('fruits.xls', keep_default_na=False)
| Date | Fruit Name | Color | |
|---|---|---|---|
| 0 | Fruits A | ||
| 1 | 11/24/09 | Apple | Red |
| 2 | 05/24/10 | Banana | Yellow |
| 3 | |||
| 4 | 11/24/09 | Orange | Orange |
| 5 | 05/24/10 | Grapes | Purple |
格式化列
Tablib提供add_formatter函數(shù)用于向Dataset對(duì)象添加自定義格式化程序,以便在導(dǎo)出數(shù)據(jù)時(shí)按照指定格式進(jìn)行格式化。
# 創(chuàng)建一個(gè)空的 Dataset 對(duì)象
data = tablib.Dataset()
# 添加數(shù)據(jù)到 Dataset
data.headers = ['name','age','role']
data.append(['John', 28, 'Developer'])
data.append(['Amy', 25, 'Designer'])
# 定義一個(gè)自定義的格式化函數(shù)
def custom_formatter(val):
if isinstance(val, int):
return f'Age: {val}'
elif isinstance(val, str):
return val.upper()
else:
return str(val)
# 添加自定義格式化函數(shù)到 Dataset
# 第一個(gè)參數(shù)可以為列號(hào)
data.add_formatter(0,custom_formatter)
# 如果有列名,也可以指定列名
data.add_formatter('age',custom_formatter)
# 導(dǎo)出數(shù)據(jù)并應(yīng)用自定義格式化函數(shù)
data.df
| name | age | role | |
|---|---|---|---|
| 0 | JOHN | Age: 28 | Developer |
| 1 | AMY | Age: 25 | Designer |
創(chuàng)建子表格
# 創(chuàng)建表格
data = tablib.Dataset()
data.headers = ['Name', 'Age','Profession']
data.append(['Alice', 25, 'Doctor'])
data.append(['Bob', 30, 'Doctor'])
data.append(['Jack', 28, 'Engineer'])
# subset方法用于從現(xiàn)有的數(shù)據(jù)集中選擇子集
# rows表示行號(hào),rows=[0, 2]表示選擇第0行和第2行
sub_data = data.subset(rows=[0, 2], cols=['Name', 'Profession'])
sub_data.df
| Name | Profession | |
|---|---|---|
| 0 | Alice | Doctor |
| 1 | Jack | Engineer |
2 參考
- tablib
- tablib-doc。
總結(jié)
以上是生活随笔為你收集整理的[python] 基于Tablib库处理表格数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 学会XPath,轻松抓取网页数据
- 下一篇: python汉字排序_Python中文排