日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 用 xlwings 处理 Excel 中的重复数据

發布時間:2024/3/24 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 用 xlwings 处理 Excel 中的重复数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

xlwings 簡介

xlwings 是一個 Python 庫。簡化了 Python 和 Excel 通信。
xlwings - 讓Excel跑得飛快!

本文寫作背景 & 需求 & 方案

因前幾個月幫在醫院工作的朋友現學現賣用VBA寫了段程序,處理2個excel文檔的數據到第3個Excel文檔上,有模板數據,有圖表,怕數據出錯,反復測試,折騰了有2天才弄出來。在摸索怎么用VBA開發的過程中發現,VBA開發太痛苦了。
前幾天我無意間看到了一篇文章的標題 叫做 插上翅膀,讓Excel飛起來——xlwings ,我被標題吸引住了,看到了有這么個東西。
更巧的是昨天朋友又讓我幫她處理個Excel問題,這次的需求非常簡單,為:

1. 只有一張只有3列的表
2. 如果表中存在兩行或多行數據,它們的第2列和第3列數據都相同,第1列數據是否相同不考慮
3. 那么就只保留任意一行數據即可。

即:刪除表中后兩列數據相同的多余的行

于是乎想到了xlwings這個東西,想試一試,看看怎么玩(我還不會python的HelloWorld)

效果圖如下:

解決方案

  • 代碼見本文編碼部分,推薦方案代碼2,實際情況不推薦!(2023/01/08更新:現在也不推薦方案代碼2了,推薦方案代碼3)
  • 推薦優先不編碼!使用 WPS 或 Excel 已有功能去實現,如下圖,點幾下就OK了。本文旨在站在程序猿的角度玩一把編碼實現,嘗試下python的味道。

環境準備

推薦使用 anaconda 解決環境問題,具體用法自行百度

Python3 安裝

注意:安裝時提供管理員權限,否則容易出錯。

庫安裝

pip install 庫名[=版本號]

  • xlwings

    pip install xlwings

  • 其他庫(看需安裝)

    • NumPy
    • NumPy Matplotlib
    • pandas

Python 語法基礎

>>> def fib(n): >>> a, b = 0, 1 >>> while a < n: >>> print(a, end=' ') >>> a, b = b, a+b >>> print() >>> fib(1000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

中文報錯

需要首行加入 #coding=utf-8 或 # -*- coding: UTF-8 -*-

內置函數

https://docs.python.org/zh-cn/3.7/library/functions.html

  • type() 用于檢測一個數據的數據類型,非常有用。效果如:<class ‘list’> <class ‘xlwings.main.Range’>
  • str() 轉為字符串
  • int() 轉為int
  • len() 獲取序列或集合對象長度
  • max() 返回可迭代對象中最大值,等等其他數學函數
  • round(num, n) 四舍五入保留n位小數的函數
  • input("請輸入:") 等待接收用戶輸入數據并將接收數據返回

嚴格代碼對齊

因為沒有大括號,必須要嚴格代碼對齊,否則語義可能不同甚至報錯!

序列類型 — list, tuple, range

  • 列表list 是可變序列

    class list([iterable])?
    使用一對方括號來表示空列表: []
    使用方括號,其中的項以逗號分隔: [a], [a, b, c]
    使用列表推導式: [x for x in iterable]
    使用類型的構造器: list() 或 list(iterable)

  • 元組tuple是不可變序列,通常用于儲存異構數據的多項集

    class tuple([iterable])
    使用一對圓括號來表示空元組: ()
    使用一個后綴的逗號來表示單元組: a, 或 (a,)
    使用以逗號分隔的多個項: a, b, c or (a, b, c)
    使用內置的 tuple(): tuple() 或 tuple(iterable)
    tuple(‘abc’) 返回 (‘a’, ‘b’, ‘c’) 而 tuple( [1, 2, 3] ) 返回 (1, 2, 3)。 如果沒有給出參數,構造器將創建一個空元組 ()

  • 范圍range 類型表示不可變的數字序列,通常用于在 for 循環中循環指定的次數。

    class range(stop)
    class range(start, stop[, step])

  • 舉例

    >>> 3,0,-1 (3, 0, -1) >>> (3,0,-1) # 同上,為元組,括號大多可省,不建議省 (3, 0, -1) >>> range(3,0,-1) # range ,表示開始為3,結束為1,步長為-1的整數范圍 range(3, 0, -1) >>> for i in range(3,0,-1): ... print(i) ... 3 2 1

集合/字典

  • 集合可用多種方式來創建:
    使用花括號內以逗號分隔元素的方式: {‘jack’, ‘sjoerd’}
    使用集合推導式: {c for c in ‘abracadabra’ if c not in ‘abc’}
    使用類型構造器: set(), set(‘foobar’), set([‘a’, ‘b’, ‘foo’])

  • 字典可用多種方式來創建:
    使用花括號內以逗號分隔 鍵: 值 對的方式: {‘jack’: 4098, ‘sjoerd’: 4127} or {4098: ‘jack’, 4127: ‘sjoerd’}
    使用字典推導式: {}, {x: x ** 2 for x in range(10)}
    使用類型構造器: dict(), dict([(‘foo’, 100), (‘bar’, 200)]), dict(foo=100, bar=200)

for 循環,和其他語言還真不一樣

語法格式只有 for-in 這一種格式

"for" target_list "in" expression_list ":" suite["else" ":" suite]`

因此,如果想動態修改循環次數,可使用while替換

r = 3 for i in range(r):print(i)# 下面的修改對for循環沒有用,因為i的值會被下次循環覆蓋,i的值在range范圍內i-=1r-=2 # 輸出: # 0 # 1 # 2

字符串拼接

加號用于字符串拼接時,需要注意非字符串需要str()函數處理才可以,如:"你好" + str(123) ;或 print("你好%s"%123) 或更簡單的print(a, b, c...) 或 format()方法拼接:
"你好{1}{0}{2}".format(1,2,3) # ‘你好213’ "你好{}{}{}".format(1,2,3) # ‘你好123’ 等

冒號

  • if / for 等語句中,分割代碼作用

    >>> if x < 0: ... x = 0 ... print('Negative changed to zero') ... elif x == 0: ... print('Zero') ... elif x == 1: ... print('Single') ... else: ... print('More')
  • 列表(類似C語言數組,Python中沒有數組)引用中

    >>> x [1, 3, 5, 8, 9] >>> x[1:3] # 索引范圍 [3, 5] >>> x[:] # 全部 [1, 3, 5, 8, 9]

    包含3個子列表的一維列表 X=array( [[1,2,3,4], [5,6,7,8], [9,10,11,12]] )
    X[:, 0] 就是取矩陣X的所有行的第0列的元素,X[:,1] 就是取所有行的第1列的元素
    X[:, m:n] 即取矩陣X的所有行中的的第m到n-1列數據,含左不含右

  • 雙冒號

    推薦:官方文檔在Range處的解釋(點擊查看)

    a[x:y:z]
    x表示切片起點,y表示切片終點,z表示步長,步長z默認為1;
    如果z為正數,則默認x、y分別為列表的開始和結束索引,內容的公式為 a[i] = start + step*i 其中 i >= 0 且 r[i] < stop
    如果z為負數,表示倒序,內容的公式仍然為 a[i] = start + step*i,但限制條件改為 i >= 0 且 a[i] > z.
    如果 a[0] 不符合值的限制條件,則該 a 對象為空。 a 對象確實支持負索引(最后一個元素的索引是-1,倒數第二個元素索引為-2),但是會將其解讀為從正索引所確定的序列的末尾開始索引;
    如果z為0,則報錯。

    如下:

    >>> a = [1,3,5,8] >>> a[::] [1, 3, 5, 8] >>> a[1:3:] [3, 5] >>> a[::2] [1, 5] >>> a[::-1] [8, 5, 3, 1] >>> a[::-2] [8, 3] >>> a[1::-2] [3] >>> a[0:3:-1] [] >>> a[3:0:-1] [8, 5, 3] >>> a[3:0:-2] [8, 3] >>> a[1:3:0] Traceback (most recent call last):File "<stdin>", line 1, in <module> ValueError: slice step cannot be zero

    range(10)[::2] 表示范圍 [0, 10) 步長為2的切片

    >>> range(10)[::2] range(0, 10, 2)
  • 切片完全指南(語法篇)

  • [xx for xx in yy] 鏈表推導式

  • for 循環
    遍歷列表的四種方法

https://www.runoob.com/python3/python3-class.html

class people:#定義基本屬性name = ''age = 0#定義私有屬性,私有屬性在類外部無法直接進行訪問__weight = 0#定義構造方法def __init__(self,n,a,w):self.name = nself.age = aself.__weight = wdef speak(self):print("%s 說: 我 %d 歲。" %(self.name,self.age))# 實例化類 p = people('runoob',10,30) p.speak()

模塊和包

https://www.runoob.com/python3/python3-module.html

  • 模塊,是一個python文件。包,是一個包含若干模塊的文件夾。
  • 模塊導入方式
  • import 模塊名 [as 別名]
  • from 模塊名 import <成員名1 [as 別名1], 成員名2 [as 別名2],...> 或 from 包名 import *
  • 使用方式
    有別名的使用別名,導入成員的可直接使用成員,否則使用 模塊名.成員
  • 包導入方式類似,包中必須包含文件__init__.py ,__all__

python 標準庫

python 標準庫
常用標準庫——菜鳥教程

  • sys
    print(sys.argv) # 程序執行參數
    print(sys.platform) # 系統平臺
    sys.exit()
    sys.exit(“崩了”)
  • pprint
    pprint.pprint(sys.modules) # 模塊字典
    print(sys.path) # 模塊搜索路徑
  • os
    pprint.pprint(os.environ) # 格式化打印系統環境變量
    print(os.environ[“path”]) # 打印path
    os.system(“ls”) # 執行系統命令
    print(os.getcwd()) # 當前的工作目錄
  • 字符串正則匹配
  • 數學
  • 日期和時間
  • 數據壓縮
  • 訪問互聯網

零散知識點

  • __name__ 屬性,主程序的該屬性值為 __main__
  • dir() 函數,可以找到模塊內定義的所有名稱

編碼

本需求方案代碼 1 (不推薦)

該代碼雖然能得到正確的結果,但是 for i in range(rows-1): 語句內部雖然有對 rows 值的修改,但是i 在下次循環時又會被重新賦值,i 在下次循環的取值依然不會因循環體內部對 rows 的改變而改變。i 始終會將所有的 [0, rows-1) 內的整數值取完。可參見官方 for 語句解釋

#coding=utf-8 # 首行作用:防止中文亂碼 import xlwings as xw import operator# 打開Excel程序,默認設置為程序可見,只打開不新建 app = xw.App(visible=True,add_book=False) wb = xw.Book('test.xls') sht = wb.sheets[0]rng = sht.range('A1').expand('table') rows = rng.rows.count cols = rng.columns.count print(str(rows)+", "+ str(cols))# 將表中數據轉為二維數組格式 all = sht.range((1,1),(rows,cols)).valuefor i in range(rows-1):print("--"+str(i)+"---")print(range(rows-1,i,-1))for j in range(rows-1,i,-1):# print(str(i)+", "+str(j))# 先用strip()去除單元格數據中首尾空白,防止數據因空白影響結果if operator.eq(all[i][1].strip(),all[j][1].strip()) and operator.eq(all[i][2].strip(),all[j][2].strip()):# print(all[j])# print(str(j))rng.rows[j].api.EntireRow.Delete()del all[j]rows-=1wb.save() wb.close() app.quit()

方案代碼2 (推薦)(2023/01/08更新:不再推薦這種自寫算法方案方式)

#coding=utf-8 import xlwings as xw# app = xw.App(visible=True, add_book=False) wb = xw.Book('ok.xls') # wb = app.books.open(r'D:/cuncaojin/desktop/ok.xls') # wb = xw.Book(r'D:/cuncaojin/desktop/ok.xls') sht = wb.sheets[0]# myList = [['2018年國家基本藥物采購目錄', '阿苯達唑', '片劑'], ['2018年國家基本藥物采購目錄', '阿法骨化醇', '片劑'], ['2018年國家 基本藥物采購目錄', '阿米卡星', '注射液'], ['2018年國家基本藥物采購目錄', '阿莫西林', '膠囊'], ['其他目錄', '阿莫西林', '顆粒劑'], ['其他目錄', '阿莫西林', '干混懸劑'], ['其他目錄', '阿莫西林', '分散片'], ['其他目錄', '阿莫西林', '膠囊'], ['2018年國家基本藥物采購目錄', '阿莫西林', '顆粒劑'], ['常用低價藥品基本藥物目錄', '阿莫西林', '分散片2'], ['2018年國家基 本藥物采購目錄', '阿莫西林', '膠囊'], ['常用低價藥品基本藥物目錄', '阿莫西林', '分散片'], ['2018年國家基本藥物采購目錄', '阿莫西林3', '膠囊'], ['2018年國家基本藥物采購目錄', '阿莫西林', '膠囊'], ['2018年國家基本藥物采購目錄', '阿莫西林', ' 膠囊']] myList = sht[0,0].current_region.value# print(len(myList),"\n", myList)i = 0 while i<len(myList)-1:for j in range(len(myList)-1,i,-1):if myList[i][1].strip()==myList[j][1].strip() and myList[i][2].strip()==myList[j][2].strip():# 移除重復數據myList.remove(myList[j])# 補償刪除造成的數據遷移i-=1i+=1sht['F1'].value = myList # sht['F1'].current_region.autofit() # sht['F1'].current_region.color = (221,170,244)# 打印最終數據行數 print("最終有效數據行數:%d"%len(myList))wb.save() wb.close() # 有時quit、甚至使用kill都無法關閉Excel # app.quit() # app.kill()# 退出Excel應用 for app in xw.apps:app.quit()

方案代碼3 (推薦,更新于2023/01/08)

得助于CSDN工具里chatgpt 引擎力量,讓我初步了解了pandas庫這么好用。加上報錯自行百度,最終有此方案更新。

原表格數據

處理后表格數據

# 首先要安裝依賴庫 # pip install pandas # python -m pip install openpyxldef deal_excel():import pandas as pddf = pd.read_excel('filename.xlsx')print(df)# 正則去除整個表中所有空白符df.replace('\s+', '', regex=True, inplace=True)# 去除“目錄”列中每個單元格數據兩端的空白符# df['目錄'] = df['目錄'].str.strip()print("///")print(df)df = df.drop_duplicates(subset=['目錄', '藥品名'], keep="first", inplace=False)print("///")print(df)# header為false則不要表頭df.to_excel('filename.xlsx', index=False, header=True)# 注意:pycharm中python方法間要保持至少兩行空行 if __name__ == '__main__':deal_excel()

通過以上腳本,處理了帶有空白符數據的表格,日志如下:

目錄 藥品名 類型 0 2018年國家基本藥物采購目錄 阿苯達唑 片劑 1 2018年國家基本藥物采購目錄 阿法骨化醇 片劑 2 2018年國家 基本藥物采購目錄 阿米卡星 注射液 3 2018年國家基本藥物采購目錄 阿莫西林 膠囊 4 其他目錄 阿莫西林 顆粒劑 5 其他目錄 阿莫西林 干混懸劑 6 其他目錄 阿莫西林 分散片 7 其他目錄 阿莫西林 膠囊 8 2018年國家基本藥物采購目錄 阿莫西林 顆粒劑 9 常用低價藥品基本藥物目錄 阿莫西林 分散片2 10 2018年國家基 本藥物采購目錄 阿莫西林 膠囊 11 常用低價藥品基本藥物目錄 阿莫西林 分散片 12 2018年國家基本藥物采購目錄 阿莫西林3 膠囊 13 2018年國家基本藥物采購目錄 阿莫西林 膠囊 14 2018年國家基本藥物采購目錄 阿莫西林 膠囊 ///目錄 藥品名 類型 0 2018年國家基本藥物采購目錄 阿苯達唑 片劑 1 2018年國家基本藥物采購目錄 阿法骨化醇 片劑 2 2018年國家基本藥物采購目錄 阿米卡星 注射液 3 2018年國家基本藥物采購目錄 阿莫西林 膠囊 4 其他目錄 阿莫西林 顆粒劑 5 其他目錄 阿莫西林 干混懸劑 6 其他目錄 阿莫西林 分散片 7 其他目錄 阿莫西林 膠囊 8 2018年國家基本藥物采購目錄 阿莫西林 顆粒劑 9 常用低價藥品基本藥物目錄 阿莫西林 分散片2 10 2018年國家基本藥物采購目錄 阿莫西林 膠囊 11 常用低價藥品基本藥物目錄 阿莫西林 分散片 12 2018年國家基本藥物采購目錄 阿莫西林3 膠囊 13 2018年國家基本藥物采購目錄 阿莫西林 膠囊 14 2018年國家基本藥物采購目錄 阿莫西林 膠囊 ///目錄 藥品名 類型 0 2018年國家基本藥物采購目錄 阿苯達唑 片劑 1 2018年國家基本藥物采購目錄 阿法骨化醇 片劑 2 2018年國家基本藥物采購目錄 阿米卡星 注射液 3 2018年國家基本藥物采購目錄 阿莫西林 膠囊 4 其他目錄 阿莫西林 顆粒劑 9 常用低價藥品基本藥物目錄 阿莫西林 分散片2 12 2018年國家基本藥物采購目錄 阿莫西林3 膠囊

吐槽

順便吐槽一下chatgpt,真是惡心透了,禁止咱們國家使用,明白地搞壟斷、搞封鎖。國內想使用該功能太麻煩了,要么搞國外服務器代理之類,要么掏錢使用國內中介服務,如使用CSDN的這個服務只免費使用不到5次,再想用就要辦VIP才能用。

給自己看的其它代碼

更多用法可訪問本文參考鏈接部分,強烈建議看Python 官方api 、xlwings 官方api 和 Excel 官方api 。

import matplotlib.pyplot as plt import xlwings as xwimport pandas as pd import numpy as npimport osexit = os.path.exists(r'E:\yg\desktop\test.xlsx')app=xw.App(visible=True,add_book=False)if(exit):wb = xw.Book(r'E:\yg\desktop\test.xlsx') else:wb=app.books.add()sht = wb.sheets[0]df = pd.DataFrame(np.random.rand(7, 4), columns=['aaa', 'bb', 'c', 'd']) ax = df.plot(kind='bar') fig = ax.get_figure() sht.pictures.add(fig, name='MyPlot', update=True)wb.save(r'E:\yg\desktop\test.xlsx') wb.close() app.quit()

幫助

因沒接觸過python,也不懂VBA,因此本文內容可能存在若干不當或錯誤,如有發現,敬請斧正。

參考

  • Python 官方標準庫
  • Python API
  • [菜鳥教程——Python 3 教程
  • 菜鳥教程——Python 基礎教程
  • xlwings 官方API 中文
  • xlwings 官方文檔 英文
  • Range.EntireRow 屬性 (Excel)
  • xlwings 項目含Demo
  • 插上翅膀,讓Excel飛起來——xlwings
  • 使用python繪制常用的圖表
  • Pandas 教程
  • python numpy數組中冒號的使用
  • python中雙冒號[::]切片的作用
  • Python_Python遍歷列表的四種方法
  • Python 中形如 xx for xx in yy 的鏈表推導式
  • Pandas中如何去掉空格
  • 51_Pandas (to_excel) 編寫 Excel 文件 (xlsx, xls)
  • 總結

    以上是生活随笔為你收集整理的python 用 xlwings 处理 Excel 中的重复数据的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。