【實戰】再見Excel,我能自由定製表格

不少開發者說自從有了 Python/Pandas,Excel 都不怎麼用了,用它來處理與可視化表格很是快速。python

下面我來舉幾個例子。app

1. 刪除重複行和空行

咱們直接用dict.fromkeys的方法把當前的數據轉爲字典,默認的值爲None由於用不到,也就無所謂了。而後咱們再用list直接對結果進行類型轉換,轉換爲list。ide

In [135]:
for row in rows4:
    print(row)
('name', 'address')
('tom li', 'beijing')
('tom li', 'beijing')
('',)
('mary wang', 'shandong')
('mary wang', 'shandong')
('',)
('de8ug', 'guangzhou')
In [148]:
dict.fromkeys(rows4)
Out[148]:
{('name', 'address'): None,
 ('tom li', 'beijing'): None,
 ('',): None,
 ('mary wang', 'shandong'): None,
 ('de8ug', 'guangzhou'): None}
In [137]:
list(dict.fromkeys(rows4))
Out[137]:
[('name', 'address'),
 ('tom li', 'beijing'),
 ('',),
 ('mary wang', 'shandong'),
 ('de8ug', 'guangzhou')]

這時候,重複數據直接去掉了,注意咱們這裏的dict是python3新版本的,因此順序沒有影響,若是你還在用python2或者python3.5如下,建議升級一下python版本。函數

接下來,就是空數據的處理了。觀察('',)是個元組,第一個位置的數據爲空字符串,那麼總體長度爲1,能夠直接經過循環來去掉。這裏的循環咱們能夠用Python中的語法糖寫法,直接一行搞定,最後加個判斷只留下長度大於1,最後用list轉換爲列表。測試

In [179]:
list(x for x in dict.fromkeys(rows4) if len(x[0])>1)
Out[179]:
[('name', 'address'),
 ('tom li', 'beijing'),
 ('mary wang', 'shandong'),
 ('de8ug', 'guangzhou')]

上面的研究搞定了,直接把研究結果放到函數中解決重複行和空行的問題。調試

注意這時候咱們處理的行數據,因此就再也不按列循環了。並且,當前的sheet中處理以後,每一行的內容都會修改位置或刪除。因此咱們先用old_rows = [x for x in sheet.values]取到舊的每一行的數據,注意這裏的sheet後直接用values取到數據,而不是cell對象。這裏的old_rows是個列表,就能夠用剛纔的研究直接轉爲刪除重複和空行的數據了。excel

接下來,用sheet.delete_rows(1, sheet.max_row)
刪除全部行,第一個參數表示從第一行開始,第二個參數爲最大行數。最後,用循環新的行數據的方式,把新數據寫入當前的sheet。code

In [189]:
def handle_duplicate(wb, sheetname):
    """
    去除重複行,空行
    先取出每一行,清空sheet,處理後寫回
    """
    print(f'開始處理工做表:{sheetname}'.center(18, '-'))
    sheet = wb[sheetname]
    old_rows = [x for x in sheet.values]
    print('修改前:', old_rows)
    new_rows = list(x for x in dict.fromkeys(old_rows) if len(x[0])>1)
    print('修改後-》》', new_rows)

    # 刪除全部行
    sheet.delete_rows(1, sheet.max_row)
    # 寫入新數據
    for row in new_rows:
        sheet.append(row)

運行測試,查看結果。再說一次,必定記得測試啊!若是有錯誤就根據錯誤提示,查看代碼,反覆調試,去除bugs。對象

In [190]:
wb = load_data()
handle_duplicate(wb, '重複行')
save_as(wb)

2.刪除空格

刪除空格也須要用到字符串的函數,因此這裏仍是簡單研究一下。若是咱們想去除字符串中間的空格,能夠用split默認進行分割,而後把分割的結果用’’.join方法鏈接起來就能夠了。注意join前是空的字符串。這裏也用不到strip去除兩端的空格了,由於split分割後只有幾個最後的字符串組成的列表。blog

In [192]:
a="a b c   "
In [194]:
a.strip()
Out[194]:
'a b c'
In [195]:
a.split()
Out[195]:
['a', 'b', 'c']
In [196]:
''.join(a.split())
Out[196]:
'abc'
In [ ]:

研究成功後,寫入函數。此次命名爲handle_blank。

In [197]:
def handle_blank(wb, sheetname):
    """
    按列循環, 經過參數確認目標
    """
    print(f'開始處理工做表:{sheetname}'.center(18, '-'))
    sheet = wb[sheetname]
    for col in sheet.iter_cols():  # 不加參數,循環全部列
        for cell in col:
            print('修改前:', cell.value, end='')
            cell.value = ''.join(cell.value.split())
            print('修改後-》》',cell.value)
In [198]:
handle_blank(wb, '空格')

3.修改日期和時間格式

有時候,咱們須要對錶格中時間相關的單元格進行格式修改,這裏須要用到Python中時間模塊datetime,將須要的格式進行拼接後,用strftime進行轉換。

假設這裏咱們想把以前簡單的1/11月日格式,更改成年月日的樣式,中間加上分隔符/或-,就須要用"%x"或"%Y-%m-%d"來進行操做了。注意這裏的%加字母都是官方定義好的格式而已,咱們用到時候進行拼接,傳給函數就能夠了。

具體更多的拼接格式以下:

In [199]:
import datetime
In [209]:
d=datetime.datetime(2019,1,11)
In [203]:
d.strftime("%x")
Out[203]:
'01/11/19'
In [205]:
d.strftime("%Y-%m-%d")
Out[205]:
'2019-01-11'

研究完成後,咱們編寫函數。

首先須要用m, d = cell.value.split('/')把以前簡單的日期進行分割,獲得m,表明月份和日期,而後用datetime進行轉換,生成時間相關的對象day,注意裏面的參數是數字,因此用int轉換,最後把day進行格式化輸出。編寫函數後,必定記得測試。

In [218]:
def handle_time(wb, sheetname):
    """
    按列循環, 經過參數確認目標
    """
    print(f'開始處理工做表:{sheetname}'.center(18, '-'))
    sheet = wb[sheetname]
    for col in sheet.iter_cols(max_col=1, min_row=2):  # 找到時間的列, 第一列,從第二行開始
        for cell in col:
            print('修改前:', cell.value, end='')
            m, d = cell.value.split('/')
            day = datetime.datetime(2019, int(m), int(d))
            cell.value = day.strftime("%Y-%m-%d")
            print('修改後-》》',cell.value)

In [220]:
wb = load_data()
handle_time(wb, '時間')
save_as(wb)

4.修復數字和符號

接下來,處理數字和符號相關的操做。加入咱們以前的價格,不少是有小數點的,這時候還想保存兩位小數,並加上人民幣符號爲前綴。就須要新的一波研究了。

有小數點,一是要保證位數,咱們這裏要求2位,二是要對多餘的位數四捨五入。能夠有如下倆個方式完成,一個用Decimal一個用round,兩個的區別是Decimal("0.00")指定位數後,會自動補0,而round遇到0就自動舍掉了。並且round在四捨五入的計算中,還有點特殊。具體可查看官方文檔。

咱們這裏用Decimal來完成函數內相關操做。記得測試啊!

In [227]:
from decimal import Decimal
In [240]:
a = 3.1
b=Decimal(a).quantize(Decimal("0.00"))
print(b)
3.10
In [244]:
round(a,2)  # 位數自動省略0
Out[244]:
3.1

In [247]:
def handle_num(wb, sheetname):
    """
    按列循環, 經過參數確認目標
    """
    print(f'開始處理工做表:{sheetname}'.center(18, '-'))
    sheet = wb[sheetname]
    for col in sheet.iter_cols(min_col=3, max_col=3, min_row=2):  # 找到時間的列, 第一列,從第二行開始
        for cell in col:
            print('修改前:', cell.value, end='')
#             cell.value = round(float(cell.value), 3)
            cell.value = '¥' + str(Decimal(cell.value).quantize(Decimal("0.00")))
            print('修改後-》》',cell.value)
In [249]:
wb = load_data()
handle_num(wb, '數字符號')
save_as(wb)

9元微專欄,帶你《用Python玩轉excel》

還有羣答疑服務哦↓

相關文章
相關標籤/搜索