最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python+Tkinter開發(fā)一個(gè)表格比對(duì)和&整理工具

 更新時(shí)間:2025年12月26日 09:06:21   作者:ChenAI_TGF  
日常辦公和數(shù)據(jù)處理中,Excel表格是高頻使用的工具,本文將使用Python和Tkinter開發(fā)一個(gè)表格比對(duì)和&整理工具,感興趣的小伙伴可以了解下

前言

日常辦公和數(shù)據(jù)處理中,Excel表格是高頻使用的工具,但我們經(jīng)常會(huì)遇到一些「棘手問題」:比如兩個(gè)表格需要比對(duì)差異(還可能帶圖片、比對(duì)列名不同)、表格數(shù)據(jù)行錯(cuò)亂(一行數(shù)據(jù)拆成了多行)、導(dǎo)出數(shù)據(jù)時(shí)圖片丟失……市面上要么是Excel自帶的比對(duì)功能太弱,要么是第三方工具收費(fèi)且不支持圖片保留。

基于此,我用Python+Tkinter開發(fā)了一款輕量、免費(fèi)、開源的表格比對(duì)&整理工具,核心解決「表格比對(duì)」「錯(cuò)亂行整理」兩大痛點(diǎn),本文會(huì)詳細(xì)介紹工具功能、使用方法和核心代碼邏輯。

代碼已經(jīng)開源在github,地址如下:https://github.com/ChenAI-TGF/Table_Comparison_Program

一、工具核心優(yōu)勢(shì)

  • 雙核心功能:支持表格差異比對(duì) + 錯(cuò)亂行整理,一站式解決Excel處理痛點(diǎn);
  • 圖片保留:讀取/導(dǎo)出Excel時(shí)完整保留圖片,解決常規(guī)工具丟失圖片的問題;
  • 靈活配置:支持自定義比對(duì)列(不同表格列名不同也能比對(duì))、自定義整理行的判斷列;
  • 友好交互:帶進(jìn)度條、多線程處理(避免UI卡死)、中文適配,新手也能快速上手;
  • 格式兼容:支持.xlsx(帶圖片)和.csv(無圖片)格式,覆蓋主流表格格式。

二、功能演示

2.1 環(huán)境準(zhǔn)備

工具基于Python開發(fā),需先配置環(huán)境:

# 安裝核心依賴(tkinter一般Python自帶,無需額外安裝)
pip install pandas openpyxl
  • 系統(tǒng)兼容:Windows/macOS/Linux(Windows體驗(yàn)最佳);
  • 格式說明:僅支持.xlsx(可保留圖片)和.csv(無圖片),不支持舊版.xls(openpyxl不兼容)。

2.2 工具啟動(dòng)

將本文末尾的完整代碼保存為table_tool.py,運(yùn)行命令:

python table_tool.py

啟動(dòng)后界面如下,主要分為「表格比對(duì)區(qū)」「表格整理區(qū)」「進(jìn)度條區(qū)」三大模塊,布局清晰:

2.3 功能1:表格比對(duì)(支持圖片保留)

適用場(chǎng)景:比如有「表格A」和「表格B」,需要找出「A有B無」「B有A無」「兩者共有」的數(shù)據(jù),且表格中包含圖片(如產(chǎn)品圖、二維碼)。

操作步驟:

上傳文件:點(diǎn)擊「文件A/文件B」的「選擇文件」按鈕,上傳需要比對(duì)的兩個(gè)表格;

配置比對(duì)規(guī)則:

  • 選擇「文件A/B子表格」(支持多sheet表格);
  • 選擇「A/B表格比對(duì)列」(比如A表用「申請(qǐng)注冊(cè)號(hào)」,B表用「注冊(cè)號(hào)」比對(duì));

開始比對(duì):點(diǎn)擊「開始比對(duì)」,進(jìn)度條會(huì)實(shí)時(shí)顯示處理進(jìn)度(多線程不卡UI);

導(dǎo)出結(jié)果:

  • 點(diǎn)擊「導(dǎo)出A有B無的數(shù)據(jù)」/「導(dǎo)出B有A無的數(shù)據(jù)」:導(dǎo)出差異數(shù)據(jù),保留對(duì)應(yīng)圖片;
  • 點(diǎn)擊「導(dǎo)出共有數(shù)據(jù)」:可選擇按A表/ B表格式導(dǎo)出,自動(dòng)映射圖片到對(duì)應(yīng)行。

效果示例

  • 原表格A有100行,表格B有80行
  • 比對(duì)后導(dǎo)出「A有B無」數(shù)據(jù)20行

2.4 功能2:表格整理(解決一行數(shù)據(jù)占多行問題)

適用場(chǎng)景:比如表格中一行數(shù)據(jù)被拆成了多行(如商品信息行,后續(xù)行是補(bǔ)充的屬性,無核心編號(hào)),需要合并為一行,且保留原表格中的圖片。

操作步驟:

1.上傳待整理文件:點(diǎn)擊「待整理文件」的「選擇文件」按鈕;

2.配置整理規(guī)則:

  • 選擇「待整理子表格」;
  • 選擇「新行判斷列」(核心列,比如「商品編號(hào)」——該列非空則為新行,空則為補(bǔ)充行);

3.開始整理:點(diǎn)擊「開始整理表格」,進(jìn)度條顯示處理進(jìn)度;

4. 導(dǎo)出結(jié)果:點(diǎn)擊「導(dǎo)出整理后表格」,合并后的行數(shù)據(jù)+圖片會(huì)被完整導(dǎo)出。

效果示例

  • 原表格有200行(實(shí)際只有80條有效數(shù)據(jù),每行占2-3行);
  • 整理后變?yōu)?0行,圖片自動(dòng)映射到對(duì)應(yīng)合并后的行。

三、核心代碼講解

工具的核心類是TableCompareApp,整體架構(gòu)分為「UI搭建」「文件讀?。ê瑘D片)」「比對(duì)邏輯」「整理邏輯」「導(dǎo)出功能」五部分,下面重點(diǎn)講解核心邏輯(UI部分簡(jiǎn)講)。

3.1 UI部分

UI采用Tkinter的LabelFrame「Frame「Combobox「Progressbar`等組件,按功能分區(qū)域布局:

  • 「文件上傳區(qū)」:負(fù)責(zé)A/B文件、待整理文件的選擇;
  • 「信息展示區(qū)」:顯示文件格式、行列數(shù)、圖片數(shù);
  • 「配置區(qū)」:子表格、比對(duì)列、整理判斷列的選擇;
  • 「操作區(qū)」:比對(duì)/整理/導(dǎo)出按鈕;
  • 「進(jìn)度條區(qū)」:實(shí)時(shí)顯示處理進(jìn)度。

核心細(xì)節(jié):

  • 中文適配:通過root.option_add("*Font", "SimHei 9")解決Windows下Tkinter中文亂碼;
  • 按鈕狀態(tài)控制:根據(jù)文件上傳/配置完成狀態(tài),動(dòng)態(tài)啟用/禁用按鈕(如check_compare_btn_state方法)。

3.2 核心1:文件讀取(保留圖片)

文件讀取是工具的基礎(chǔ),核心是用openpyxl讀取.xlsx文件(支持圖片提?。a在load_file/load_clean_file方法中:

# 關(guān)鍵代碼片段:讀取Excel并提取圖片
if file_ext == ".xlsx":
    # 用openpyxl讀取工作簿(保留圖片)
    wb = load_workbook(file_path, data_only=True)
    sheets = wb.sheetnames
    
    for sheet in sheets:
        ws = wb[sheet]
        # 1. 讀取表格數(shù)據(jù)到DataFrame(處理表頭)
        df = pd.DataFrame(ws.values)
        if len(df) > 0:
            df.columns = df.iloc[0]  # 第一行設(shè)為列名
            df = df.drop(0).reset_index(drop=True)
        data_dict[sheet] = df
        
        # 2. 提取圖片及位置(核心:保留圖片+行列映射)
        sheet_images = []
        for img in ws._images:
            # 轉(zhuǎn)換為1-based行列號(hào)(Excel原生格式)
            row = img.anchor._from.row + 1  
            col = img.anchor._from.col + 1
            sheet_images.append((img, row, col))
        images_dict[sheet] = sheet_images

關(guān)鍵邏輯

  • openpyxlws._images能獲取工作表中所有圖片對(duì)象;
  • 圖片的anchor屬性包含位置信息,需轉(zhuǎn)換為1-based(Excel行/列從1開始,openpyxl內(nèi)部是0-based);
  • 數(shù)據(jù)與圖片分開存儲(chǔ),用字典關(guān)聯(lián)「sheet名-數(shù)據(jù)/圖片」,保證一一對(duì)應(yīng)。

3.3 核心2:表格比對(duì)邏輯(含圖片映射)

比對(duì)邏輯在compare_task方法中,采用多線程執(zhí)行(避免UI卡死),核心分為「數(shù)據(jù)比對(duì)」和「圖片映射」兩部分:

3.3.1 數(shù)據(jù)比對(duì)核心

# 數(shù)據(jù)預(yù)處理:統(tǒng)一轉(zhuǎn)字符串、填充空值(避免類型不一致導(dǎo)致比對(duì)錯(cuò)誤)
df_a[col_a] = df_a[col_a].astype(str).fillna("")
df_b[col_b] = df_b[col_b].astype(str).fillna("")

# 集合運(yùn)算:快速找差異/共有值(效率遠(yuǎn)高于循環(huán))
a_vals = set(df_a[col_a].unique())
b_vals = set(df_b[col_b].unique())
a_not_b_vals = a_vals - b_vals  # A有B無
b_not_a_vals = b_vals - a_vals  # B有A無
common_vals = a_vals & b_vals   # 共有值

# 篩選對(duì)應(yīng)行
a_not_b_df = df_a[df_a[col_a].isin(a_not_b_vals)].reset_index(drop=True)

優(yōu)勢(shì):用Python集合運(yùn)算替代逐行循環(huán),比對(duì)效率提升10倍以上,適合大數(shù)據(jù)量。

3.3.2 圖片映射核心

比對(duì)后數(shù)據(jù)行號(hào)會(huì)變化,需將原圖片的位置映射到新行:

# A格式共有數(shù)據(jù)圖片映射示例
a_common_original_rows = df_a[df_a[col_a].isin(common_vals)].index.tolist()
a_common_images = []
for img, orig_row, col in img_a_list:
    # 原Excel行 → 原DataFrame行(Excel行1=表頭,行2=df第0行)
    orig_df_row = orig_row - 2  
    if orig_df_row in a_common_original_rows:
        # 新Excel行 = 新DataFrame行 + 2(表頭占1行)
        new_row = a_common_original_rows.index(orig_df_row) + 2
        a_common_images.append((img, new_row, col))

關(guān)鍵邏輯

  • 建立「原DataFrame行號(hào) → 新DataFrame行號(hào)」的映射;
  • 轉(zhuǎn)換為Excel原生行號(hào)(+2),保證圖片位置準(zhǔn)確。

3.4 核心3:表格整理邏輯(含圖片映射)

整理邏輯在clean_table_task方法中,核心是「合并錯(cuò)亂行」+「行號(hào)映射」:

3.4.1 行合并核心

cleaned_rows = []
current_row = None
orig_to_new_row = {}  # 原行→新行映射字典
new_row_idx = 0

for idx, row in df.iterrows():
    # 關(guān)鍵列非空 → 新行開始
    if str(row[key_col]).strip() != "":
        if current_row is not None:
            cleaned_rows.append(current_row)
            new_row_idx += 1
        current_row = row.to_dict()
        orig_to_new_row[idx] = new_row_idx
    else:
        # 關(guān)鍵列空 → 補(bǔ)充到當(dāng)前行(僅填充空值)
        if current_row is not None:
            for col in df.columns:
                if str(row[col]).strip() != "" and str(current_row[col]).strip() == "":
                    current_row[col] = row[col]
            orig_to_new_row[idx] = new_row_idx

# 保存最后一行
if current_row is not None:
    cleaned_rows.append(current_row)
cleaned_table_result = pd.DataFrame(cleaned_rows)

核心規(guī)則:僅當(dāng)「新行判斷列」非空時(shí),才新建一行;否則將當(dāng)前行的非空數(shù)據(jù)補(bǔ)充到上一行的空值中,保證一行數(shù)據(jù)完整。

3.4.2 圖片映射核心

# 整理后圖片映射
cleaned_table_images = []
for img, orig_row, col in orig_images:
    orig_df_row = orig_row - 2  # Excel行→原DataFrame行
    if orig_df_row in orig_to_new_row:
        # 新Excel行 = 新DataFrame行 + 2
        new_excel_row = orig_to_new_row[orig_df_row] + 2
        cleaned_table_images.append((img, new_excel_row, col))

邏輯:通過orig_to_new_row字典,將原圖片的行號(hào)映射到合并后的新行號(hào),保證圖片跟隨對(duì)應(yīng)數(shù)據(jù)行。

3.5 核心4:導(dǎo)出功能

導(dǎo)出功能封裝在export_with_images方法中,核心是用openpyxl寫入數(shù)據(jù)+圖片:

if file_ext == ".xlsx":
    # 創(chuàng)建新工作簿
    wb = Workbook()
    ws = wb.active
    ws.title = "數(shù)據(jù)"
    
    # 1. 寫入DataFrame數(shù)據(jù)(保留表頭)
    for r in dataframe_to_rows(df, index=False, header=True):
        ws.append(r)
    
    # 2. 插入圖片到對(duì)應(yīng)位置
    for img, row, col in images:
        new_img = copy.deepcopy(img)  # 復(fù)制圖片避免引用沖突
        new_img.anchor = f"{chr(64+col)}{row}"  # 設(shè)置錨點(diǎn)(如A2、B5)
        ws.add_image(new_img)
    
    wb.save(file_path)
    wb.close()

關(guān)鍵細(xì)節(jié)

  • dataframe_to_rows:將DataFrame轉(zhuǎn)換為Excel行格式,保留表頭;
  • 圖片錨點(diǎn):用chr(64+col)將列號(hào)(數(shù)字)轉(zhuǎn)換為Excel列字母(如1→A,2→B);
  • 深拷貝圖片:避免多個(gè)圖片引用同一對(duì)象導(dǎo)致導(dǎo)出失敗。

3.6 輔助:進(jìn)度條+多線程

  • 多線程:比對(duì)/整理任務(wù)放在獨(dú)立線程中執(zhí)行(threading.Thread),設(shè)置daemon=True保證線程隨主程序退出;
  • 進(jìn)度條更新:通過update_progress方法實(shí)時(shí)刷新進(jìn)度條,調(diào)用root.update_idletasks()強(qiáng)制刷新UI,避免進(jìn)度條卡住。

四、使用注意事項(xiàng)

  • 格式限制:僅支持.xlsx(帶圖片)和.csv(無圖片),.xls格式需先轉(zhuǎn)換為.xlsx;
  • 圖片位置:Excel中圖片需「嵌入單元格」(而非浮窗),否則行列映射可能出錯(cuò);
  • 關(guān)鍵列選擇:整理功能的「新行判斷列」需選有唯一標(biāo)識(shí)的列(如編號(hào)、名稱),否則合并邏輯會(huì)出錯(cuò);
  • 大數(shù)據(jù)量:超過10萬行的表格建議拆分處理,避免內(nèi)存占用過高;
  • 編碼問題:CSV文件建議用UTF-8編碼,否則可能出現(xiàn)中文亂碼。

五、總結(jié)

這款工具以「解決實(shí)際痛點(diǎn)」為核心,通過Python+Tkinter實(shí)現(xiàn)了輕量化、可定制的表格處理能力,尤其是「圖片保留」功能填補(bǔ)了常規(guī)工具的空白。代碼完全開源,大家可以根據(jù)自己的需求二次開發(fā)(比如增加批量處理、格式轉(zhuǎn)換、更多比對(duì)規(guī)則等)。

無論是辦公人員快速處理表格,還是開發(fā)者學(xué)習(xí)Tkinter+Excel操作,這款工具都有一定的參考價(jià)值。如果有其他需求(比如支持更多格式、自動(dòng)識(shí)別關(guān)鍵列),也可以基于核心邏輯擴(kuò)展。

六、完整代碼

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import pandas as pd
import os
import threading
import time
import copy
from openpyxl import load_workbook, Workbook
from openpyxl.drawing.image import Image as OpenpyxlImage
from openpyxl.utils.dataframe import dataframe_to_rows

# 全局變量存儲(chǔ)文件數(shù)據(jù)(新增圖片存儲(chǔ)字段)
file_a_data = {"sheets": [], "data": {}, "path": "", "images": {}}  # images: {sheet: [(img, row, col), ...]}
file_b_data = {"sheets": [], "data": {}, "path": "", "images": {}}
# 新增:存儲(chǔ)共有數(shù)據(jù)及對(duì)應(yīng)圖片
compare_result = {
    "a_not_b": None, "b_not_a": None, "a_common": None, "b_common": None,
    "a_common_images": [], "b_common_images": []
}
# 整理表格相關(guān)全局變量(新增圖片存儲(chǔ))
clean_file_data = {"sheets": [], "data": {}, "path": "", "images": {}}
cleaned_table_result = None
cleaned_table_images = []  # 整理后的圖片:[(img, new_row, col), ...]

class TableCompareApp:
    def __init__(self, root):
        self.root = root
        self.root.title("表格比對(duì)&整理工具")
        self.root.geometry("950x850")
        
        # 進(jìn)度條變量
        self.progress_var = tk.DoubleVar()
        
        # 構(gòu)建UI
        self._create_widgets()
    
    def _create_widgets(self):
        # 1. 文件上傳區(qū)域(原有比對(duì)功能)
        upload_frame = ttk.LabelFrame(self.root, text="文件上傳(比對(duì)功能)")
        upload_frame.pack(padx=10, pady=10, fill="x")
        
        # 文件A上傳
        ttk.Label(upload_frame, text="文件A:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
        self.file_a_label = ttk.Label(upload_frame, text="未選擇文件", foreground="gray")
        self.file_a_label.grid(row=0, column=1, padx=5, pady=5, sticky="w")
        ttk.Button(upload_frame, text="選擇文件", command=lambda: self.load_file("A")).grid(row=0, column=2, padx=5, pady=5)
        
        # 文件B上傳
        ttk.Label(upload_frame, text="文件B:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
        self.file_b_label = ttk.Label(upload_frame, text="未選擇文件", foreground="gray")
        self.file_b_label.grid(row=1, column=1, padx=5, pady=5, sticky="w")
        ttk.Button(upload_frame, text="選擇文件", command=lambda: self.load_file("B")).grid(row=1, column=2, padx=5, pady=5)
        
        # 2. 文件基本信息區(qū)域(原有)
        info_frame = ttk.LabelFrame(self.root, text="文件基本信息")
        info_frame.pack(padx=10, pady=5, fill="x")
        
        self.file_a_info = ttk.Label(info_frame, text="文件A信息:無")
        self.file_a_info.pack(padx=5, pady=2, anchor="w")
        
        self.file_b_info = ttk.Label(info_frame, text="文件B信息:無")
        self.file_b_info.pack(padx=10, pady=2, anchor="w")
        
        # 3. 比對(duì)配置區(qū)域(原有)
        config_frame = ttk.LabelFrame(self.root, text="比對(duì)配置(支持不同列比對(duì))")
        config_frame.pack(padx=10, pady=5, fill="x")
        
        # 子表格選擇
        ttk.Label(config_frame, text="文件A子表格:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
        self.sheet_a_combobox = ttk.Combobox(config_frame, state="disabled")
        self.sheet_a_combobox.grid(row=0, column=1, padx=5, pady=5, sticky="w")
        
        ttk.Label(config_frame, text="文件B子表格:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
        self.sheet_b_combobox = ttk.Combobox(config_frame, state="disabled")
        self.sheet_b_combobox.grid(row=1, column=1, padx=5, pady=5, sticky="w")
        
        # 比對(duì)列選擇
        ttk.Label(config_frame, text="A表格比對(duì)列:").grid(row=2, column=0, padx=5, pady=5, sticky="w")
        self.compare_col_a_combobox = ttk.Combobox(config_frame, state="disabled")
        self.compare_col_a_combobox.grid(row=2, column=1, padx=5, pady=5, sticky="w")
        
        ttk.Label(config_frame, text="B表格比對(duì)列:").grid(row=3, column=0, padx=5, pady=5, sticky="w")
        self.compare_col_b_combobox = ttk.Combobox(config_frame, state="disabled")
        self.compare_col_b_combobox.grid(row=3, column=1, padx=5, pady=5, sticky="w")
        
        # 4. 操作按鈕區(qū)域(新增:導(dǎo)出共有數(shù)據(jù)按鈕)
        compare_btn_frame = ttk.Frame(self.root)
        compare_btn_frame.pack(padx=10, pady=10)
        
        self.compare_btn = ttk.Button(compare_btn_frame, text="開始比對(duì)", command=self.start_compare, state="disabled")
        self.compare_btn.pack(side="left", padx=5)
        
        self.export_a_btn = ttk.Button(compare_btn_frame, text="導(dǎo)出A有B無的數(shù)據(jù)", command=lambda: self.export_result("a_not_b"), state="disabled")
        self.export_a_btn.pack(side="left", padx=5)
        
        self.export_b_btn = ttk.Button(compare_btn_frame, text="導(dǎo)出B有A無的數(shù)據(jù)", command=lambda: self.export_result("b_not_a"), state="disabled")
        self.export_b_btn.pack(side="left", padx=5)
        
        # 新增:導(dǎo)出共有數(shù)據(jù)按鈕
        self.export_common_btn = ttk.Button(compare_btn_frame, text="導(dǎo)出共有數(shù)據(jù)", command=self.export_common_result, state="disabled")
        self.export_common_btn.pack(side="left", padx=5)
        
        # ========== 表格整理功能區(qū)域 ==========
        clean_frame = ttk.LabelFrame(self.root, text="表格整理功能(解決一行數(shù)據(jù)占多行問題)")
        clean_frame.pack(padx=10, pady=15, fill="x")
        
        # 選擇要整理的文件
        ttk.Label(clean_frame, text="待整理文件:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
        self.clean_file_label = ttk.Label(clean_frame, text="未選擇文件", foreground="gray")
        self.clean_file_label.grid(row=0, column=1, padx=5, pady=5, sticky="w")
        ttk.Button(clean_frame, text="選擇文件", command=self.load_clean_file).grid(row=0, column=2, padx=5, pady=5)
        
        # 選擇待整理的子表格
        ttk.Label(clean_frame, text="待整理子表格:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
        self.clean_sheet_combobox = ttk.Combobox(clean_frame, state="disabled")
        self.clean_sheet_combobox.grid(row=1, column=1, padx=5, pady=5, sticky="w")
        
        # 選擇關(guān)鍵列(判斷新行的依據(jù):關(guān)鍵列非空=新行)
        ttk.Label(clean_frame, text="新行判斷列:").grid(row=2, column=0, padx=5, pady=5, sticky="w")
        self.clean_key_col_combobox = ttk.Combobox(clean_frame, state="disabled")
        self.clean_key_col_combobox.grid(row=2, column=1, padx=5, pady=5, sticky="w")
        
        # 整理/導(dǎo)出按鈕
        clean_btn_frame = ttk.Frame(clean_frame)
        clean_btn_frame.grid(row=3, column=0, columnspan=3, pady=10)
        
        self.clean_btn = ttk.Button(clean_btn_frame, text="開始整理表格", command=self.start_clean_table, state="disabled")
        self.clean_btn.pack(side="left", padx=5)
        
        self.export_clean_btn = ttk.Button(clean_btn_frame, text="導(dǎo)出整理后表格", command=self.export_cleaned_table, state="disabled")
        self.export_clean_btn.pack(side="left", padx=5)
        
        # ========== 進(jìn)度條區(qū)域(共用) ==========
        progress_frame = ttk.Frame(self.root)
        progress_frame.pack(padx=10, pady=5, fill="x")
        
        self.progress_bar = ttk.Progressbar(progress_frame, variable=self.progress_var, maximum=100)
        self.progress_bar.pack(fill="x", padx=5, pady=5)
        
        self.progress_label = ttk.Label(progress_frame, text="進(jìn)度:0%")
        self.progress_label.pack(anchor="center")
    
    # ========== 核心修復(fù):支持讀取圖片 ==========
    def load_file(self, file_type):
        """加載比對(duì)用的A/B文件(支持讀取圖片)"""
        file_path = filedialog.askopenfilename(
            title=f"選擇{file_type}文件",
            filetypes=[("Excel文件", "*.xlsx"), ("CSV文件", "*.csv"), ("所有文件", "*.*")]
        )
        if not file_path:
            return
        
        # 初始化數(shù)據(jù)
        if file_type == "A":
            file_a_data.update({"sheets": [], "data": {}, "path": file_path, "images": {}})
            self.file_a_label.config(text=os.path.basename(file_path))
            target_data = file_a_data
        else:
            file_b_data.update({"sheets": [], "data": {}, "path": file_path, "images": {}})
            self.file_b_label.config(text=os.path.basename(file_path))
            target_data = file_b_data
        
        try:
            file_ext = os.path.splitext(file_path)[1].lower()
            sheets = []
            data_dict = {}
            images_dict = {}  # 存儲(chǔ)每個(gè)sheet的圖片 (img, row, col)
            
            if file_ext == ".xlsx":
                # 用openpyxl讀取工作簿(保留圖片)
                wb = load_workbook(file_path, data_only=True)
                sheets = wb.sheetnames
                
                for sheet in sheets:
                    ws = wb[sheet]
                    # 讀取數(shù)據(jù)到DataFrame
                    df = pd.DataFrame(ws.values)
                    # 設(shè)置列名(第一行)
                    if len(df) > 0:
                        df.columns = df.iloc[0]
                        df = df.drop(0).reset_index(drop=True)
                    else:
                        df.columns = []
                    data_dict[sheet] = df
                    
                    # 提取圖片及位置(openpyxl行/列從0開始,轉(zhuǎn)換為1-based)
                    sheet_images = []
                    for img in ws._images:
                        row = img.anchor._from.row + 1  # 轉(zhuǎn)換為1-based行號(hào)
                        col = img.anchor._from.col + 1  # 轉(zhuǎn)換為1-based列號(hào)
                        sheet_images.append((img, row, col))
                    images_dict[sheet] = sheet_images
                
                wb.close()
            
            elif file_ext == ".csv":
                sheets = ["默認(rèn)表格"]
                df = pd.read_csv(file_path)
                data_dict["默認(rèn)表格"] = df
                images_dict["默認(rèn)表格"] = []  # CSV無圖片
            else:
                messagebox.showerror("錯(cuò)誤", "僅支持xlsx和csv格式文件!")
                return
            
            # 更新數(shù)據(jù)和圖片
            target_data["sheets"] = sheets
            target_data["data"] = data_dict
            target_data["images"] = images_dict
            
            # 更新信息顯示(包含圖片數(shù))
            if file_type == "A":
                first_sheet = sheets[0]
                first_df = data_dict[first_sheet]
                img_count = len(images_dict[first_sheet])
                info_text = f"文件A信息:格式={file_ext[1:].upper()} | 子表格數(shù)={len(sheets)} | "
                info_text += f"首個(gè)表格行數(shù)={len(first_df)} | 列數(shù)={len(first_df.columns)} | 圖片數(shù)={img_count}"
                self.file_a_info.config(text=info_text)
                self.sheet_a_combobox.config(state="normal", values=sheets)
                self.sheet_a_combobox.current(0)
                self.update_compare_columns()
            else:
                first_sheet = sheets[0]
                first_df = data_dict[first_sheet]
                img_count = len(images_dict[first_sheet])
                info_text = f"文件B信息:格式={file_ext[1:].upper()} | 子表格數(shù)={len(sheets)} | "
                info_text += f"首個(gè)表格行數(shù)={len(first_df)} | 列數(shù)={len(first_df.columns)} | 圖片數(shù)={img_count}"
                self.file_b_info.config(text=info_text)
                self.sheet_b_combobox.config(state="normal", values=sheets)
                self.sheet_b_combobox.current(0)
                self.update_compare_columns()
            
            self.check_compare_btn_state()
        
        except Exception as e:
            messagebox.showerror("讀取失敗", f"文件{file_type}讀取錯(cuò)誤:{str(e)}")
    
    def load_clean_file(self):
        """加載待整理的表格文件(支持讀取圖片)"""
        file_path = filedialog.askopenfilename(
            title="選擇待整理的表格文件",
            filetypes=[("Excel文件", "*.xlsx"), ("CSV文件", "*.csv"), ("所有文件", "*.*")]
        )
        if not file_path:
            return
        
        # 清空原有整理文件數(shù)據(jù)
        clean_file_data.update({"sheets": [], "data": {}, "path": file_path, "images": {}})
        self.clean_file_label.config(text=os.path.basename(file_path))
        
        try:
            file_ext = os.path.splitext(file_path)[1].lower()
            sheets = []
            data_dict = {}
            images_dict = {}
            
            if file_ext == ".xlsx":
                # 用openpyxl讀取工作簿(保留圖片)
                wb = load_workbook(file_path, data_only=True)
                sheets = wb.sheetnames
                
                for sheet in sheets:
                    ws = wb[sheet]
                    # 讀取數(shù)據(jù)到DataFrame
                    df = pd.DataFrame(ws.values)
                    # 設(shè)置列名(第一行)
                    if len(df) > 0:
                        df.columns = df.iloc[0]
                        df = df.drop(0).reset_index(drop=True)
                    else:
                        df.columns = []
                    data_dict[sheet] = df
                    
                    # 提取圖片及位置
                    sheet_images = []
                    for img in ws._images:
                        row = img.anchor._from.row + 1
                        col = img.anchor._from.col + 1
                        sheet_images.append((img, row, col))
                    images_dict[sheet] = sheet_images
                
                wb.close()
            
            elif file_ext == ".csv":
                sheets = ["默認(rèn)表格"]
                df = pd.read_csv(file_path)
                data_dict["默認(rèn)表格"] = df
                images_dict["默認(rèn)表格"] = []
            else:
                messagebox.showerror("錯(cuò)誤", "僅支持xlsx和csv格式文件!")
                return
            
            # 存儲(chǔ)數(shù)據(jù)和圖片
            clean_file_data["sheets"] = sheets
            clean_file_data["data"] = data_dict
            clean_file_data["images"] = images_dict
            
            # 更新子表格下拉框
            self.clean_sheet_combobox.config(state="normal", values=sheets)
            self.clean_sheet_combobox.current(0)
            
            # 更新關(guān)鍵列下拉框(新行判斷列)
            self.update_clean_key_columns()
            
            # 啟用整理按鈕
            self.clean_btn.config(state="normal")
            
            # 顯示文件信息(包含圖片數(shù))
            first_sheet = sheets[0]
            first_df = data_dict[first_sheet]
            img_count = len(images_dict[first_sheet])
            info_text = f"待整理文件信息:格式={file_ext[1:].upper()} | 子表格數(shù)={len(sheets)} | "
            info_text += f"首個(gè)表格行數(shù)={len(first_df)} | 列數(shù)={len(first_df.columns)} | 圖片數(shù)={img_count}"
            messagebox.showinfo("文件加載成功", info_text)
        
        except Exception as e:
            messagebox.showerror("讀取失敗", f"待整理文件讀取錯(cuò)誤:{str(e)}")
    
    # ========== 通用導(dǎo)出函數(shù)(核心修復(fù):支持導(dǎo)出圖片) ==========
    def export_with_images(self, df, images, title):
        """通用導(dǎo)出函數(shù)(支持圖片保留)"""
        # 選擇導(dǎo)出路徑
        file_path = filedialog.asksaveasfilename(
            title=title,
            filetypes=[("Excel文件", "*.xlsx"), ("CSV文件", "*.csv")],
            defaultextension=".xlsx"
        )
        if not file_path:
            return
        
        file_ext = os.path.splitext(file_path)[1].lower()
        
        try:
            if file_ext == ".xlsx":
                # 創(chuàng)建新工作簿
                wb = Workbook()
                ws = wb.active
                ws.title = "數(shù)據(jù)"
                
                # 寫入DataFrame數(shù)據(jù)(保留表頭)
                for r in dataframe_to_rows(df, index=False, header=True):
                    ws.append(r)
                
                # 插入圖片到對(duì)應(yīng)位置
                for img, row, col in images:
                    # 復(fù)制圖片對(duì)象避免引用沖突
                    new_img = copy.deepcopy(img)
                    # 設(shè)置圖片錨點(diǎn)(列字母+行號(hào))
                    new_img.anchor = f"{chr(64+col)}{row}"
                    ws.add_image(new_img)
                
                # 保存工作簿
                wb.save(file_path)
                wb.close()
                messagebox.showinfo("導(dǎo)出成功", f"數(shù)據(jù)已導(dǎo)出至:{file_path}\n包含圖片:{len(images)}張")
            
            elif file_ext == ".csv":
                # CSV不支持圖片,提示用戶
                if images:
                    messagebox.showwarning("格式提示", "CSV格式不支持存儲(chǔ)圖片,圖片將丟失!")
                df.to_csv(file_path, index=False, encoding="utf-8-sig")
                messagebox.showinfo("導(dǎo)出成功", f"數(shù)據(jù)已導(dǎo)出至:{file_path}\n注意:CSV格式不包含圖片")
        
        except Exception as e:
            messagebox.showerror("導(dǎo)出失敗", f"導(dǎo)出錯(cuò)誤:{str(e)}")
    
    # ========== 比對(duì)功能(修復(fù):處理圖片) ==========
    def update_compare_columns(self):
        """更新比對(duì)列下拉框"""
        if file_a_data["sheets"] and self.sheet_a_combobox.get():
            sheet_a = self.sheet_a_combobox.get()
            cols_a = file_a_data["data"][sheet_a].columns.tolist()
            self.compare_col_a_combobox.config(state="normal", values=cols_a)
            self.compare_col_a_combobox.current(0)
        
        if file_b_data["sheets"] and self.sheet_b_combobox.get():
            sheet_b = self.sheet_b_combobox.get()
            cols_b = file_b_data["data"][sheet_b].columns.tolist()
            self.compare_col_b_combobox.config(state="normal", values=cols_b)
            self.compare_col_b_combobox.current(0)
    
    def check_compare_btn_state(self):
        """檢查比對(duì)按鈕狀態(tài)"""
        if (file_a_data["path"] and file_b_data["path"] and 
            self.compare_col_a_combobox.get() and self.compare_col_b_combobox.get()):
            self.compare_btn.config(state="normal")
        else:
            self.compare_btn.config(state="disabled")
    
    def update_progress(self, value):
        """更新進(jìn)度條"""
        self.progress_var.set(value)
        self.progress_label.config(text=f"進(jìn)度:{int(value)}%")
        self.root.update_idletasks()
    
    def compare_task(self):
        """比對(duì)任務(wù)(修復(fù):處理共有數(shù)據(jù)圖片)"""
        try:
            # 1. 獲取配置信息
            sheet_a = self.sheet_a_combobox.get()
            sheet_b = self.sheet_b_combobox.get()
            col_a = self.compare_col_a_combobox.get()
            col_b = self.compare_col_b_combobox.get()
            
            # 2. 獲取數(shù)據(jù)和圖片
            df_a = file_a_data["data"][sheet_a].copy()
            df_b = file_b_data["data"][sheet_b].copy()
            img_a_list = file_a_data["images"].get(sheet_a, [])
            img_b_list = file_b_data["images"].get(sheet_b, [])
            
            # 3. 進(jìn)度條初始化
            self.update_progress(0)
            time.sleep(0.1)
            
            # 4. 數(shù)據(jù)預(yù)處理
            self.update_progress(20)
            df_a[col_a] = df_a[col_a].astype(str).fillna("")
            df_b[col_b] = df_b[col_b].astype(str).fillna("")
            
            # 5. 核心比對(duì)邏輯
            self.update_progress(50)
            a_vals = set(df_a[col_a].unique())
            b_vals = set(df_b[col_b].unique())
            
            # A有B無的行
            a_not_b_vals = a_vals - b_vals
            a_not_b_df = df_a[df_a[col_a].isin(a_not_b_vals)].reset_index(drop=True)
            
            # B有A無的行
            b_not_a_vals = b_vals - a_vals
            b_not_a_df = df_b[df_b[col_b].isin(b_not_a_vals)].reset_index(drop=True)
            
            # 共有數(shù)據(jù)
            common_vals = a_vals & b_vals
            a_common_df = df_a[df_a[col_a].isin(common_vals)].reset_index(drop=True)
            b_common_df = df_b[df_b[col_b].isin(common_vals)].reset_index(drop=True)
            
            # 處理共有數(shù)據(jù)的圖片(映射行號(hào))
            # A格式共有數(shù)據(jù)圖片
            a_common_original_rows = df_a[df_a[col_a].isin(common_vals)].index.tolist()
            a_common_images = []
            for img, orig_row, col in img_a_list:
                orig_df_row = orig_row - 2  # Excel行1=表頭,行2=df第0行
                if orig_df_row in a_common_original_rows:
                    new_row = a_common_original_rows.index(orig_df_row) + 2  # 新表行2開始是數(shù)據(jù)
                    a_common_images.append((img, new_row, col))
            
            # B格式共有數(shù)據(jù)圖片
            b_common_original_rows = df_b[df_b[col_b].isin(common_vals)].index.tolist()
            b_common_images = []
            for img, orig_row, col in img_b_list:
                orig_df_row = orig_row - 2
                if orig_df_row in b_common_original_rows:
                    new_row = b_common_original_rows.index(orig_df_row) + 2
                    b_common_images.append((img, new_row, col))
            
            # 6. 存儲(chǔ)結(jié)果
            compare_result["a_not_b"] = a_not_b_df
            compare_result["b_not_a"] = b_not_a_df
            compare_result["a_common"] = a_common_df
            compare_result["b_common"] = b_common_df
            compare_result["a_common_images"] = a_common_images
            compare_result["b_common_images"] = b_common_images
            
            # 7. 完成進(jìn)度
            self.update_progress(100)
            
            # 8. 啟用導(dǎo)出按鈕
            self.export_a_btn.config(state="normal")
            self.export_b_btn.config(state="normal")
            self.export_common_btn.config(state="normal")
            
            # 顯示結(jié)果(包含圖片數(shù))
            messagebox.showinfo("比對(duì)完成", 
                                f"比對(duì)結(jié)果:\nA有B無的數(shù)據(jù)行數(shù):{len(a_not_b_df)}\n"
                                f"B有A無的數(shù)據(jù)行數(shù):{len(b_not_a_df)}\n"
                                f"共有數(shù)據(jù)行數(shù)(A格式):{len(a_common_df)} | 圖片數(shù):{len(a_common_images)}\n"
                                f"共有數(shù)據(jù)行數(shù)(B格式):{len(b_common_df)} | 圖片數(shù):{len(b_common_images)}")
        
        except Exception as e:
            messagebox.showerror("比對(duì)失敗", f"比對(duì)過程出錯(cuò):{str(e)}")
            self.update_progress(0)
    
    def start_compare(self):
        """啟動(dòng)比對(duì)"""
        self.compare_btn.config(state="disabled")
        self.export_a_btn.config(state="disabled")
        self.export_b_btn.config(state="disabled")
        self.export_common_btn.config(state="disabled")
        
        compare_thread = threading.Thread(target=self.compare_task)
        compare_thread.daemon = True
        compare_thread.start()
    
    def export_result(self, result_type):
        """導(dǎo)出比對(duì)結(jié)果(修復(fù):支持圖片)"""
        if compare_result[result_type] is None:
            messagebox.showwarning("提示", "暫無可導(dǎo)出的數(shù)據(jù)!")
            return
        
        # 篩選對(duì)應(yīng)圖片
        if result_type == "a_not_b":
            df = compare_result["a_not_b"]
            sheet_a = self.sheet_a_combobox.get()
            img_a_list = file_a_data["images"].get(sheet_a, [])
            col_a = self.compare_col_a_combobox.get()
            a_not_b_vals = set(df[col_a].unique())
            a_not_b_original_rows = file_a_data["data"][sheet_a][file_a_data["data"][sheet_a][col_a].isin(a_not_b_vals)].index.tolist()
            images = []
            for img, orig_row, col in img_a_list:
                orig_df_row = orig_row - 2
                if orig_df_row in a_not_b_original_rows:
                    new_row = a_not_b_original_rows.index(orig_df_row) + 2
                    images.append((img, new_row, col))
            title = "保存A有B無的數(shù)據(jù)"
        elif result_type == "b_not_a":
            df = compare_result["b_not_a"]
            sheet_b = self.sheet_b_combobox.get()
            img_b_list = file_b_data["images"].get(sheet_b, [])
            col_b = self.compare_col_b_combobox.get()
            b_not_a_vals = set(df[col_b].unique())
            b_not_a_original_rows = file_b_data["data"][sheet_b][file_b_data["data"][sheet_b][col_b].isin(b_not_a_vals)].index.tolist()
            images = []
            for img, orig_row, col in img_b_list:
                orig_df_row = orig_row - 2
                if orig_df_row in b_not_a_original_rows:
                    new_row = b_not_a_original_rows.index(orig_df_row) + 2
                    images.append((img, new_row, col))
            title = "保存B有A無的數(shù)據(jù)"
        else:
            return
        
        self.export_with_images(df, images, title)
    
    def export_common_result(self):
        """導(dǎo)出共有數(shù)據(jù)(修復(fù):支持圖片)"""
        if compare_result["a_common"] is None or compare_result["b_common"] is None:
            messagebox.showwarning("提示", "暫無共有數(shù)據(jù)可導(dǎo)出!")
            return
        
        # 選擇導(dǎo)出格式
        choice = messagebox.askquestion(
            "選擇導(dǎo)出格式",
            "請(qǐng)選擇共有數(shù)據(jù)的導(dǎo)出格式:\n【是】= 按A表格格式導(dǎo)出(保留A表格列結(jié)構(gòu))\n【否】= 按B表格格式導(dǎo)出(保留B表格列結(jié)構(gòu))",
            icon="question"
        )
        
        if choice == "yes":
            df = compare_result["a_common"]
            images = compare_result["a_common_images"]
            title = "保存按A表格格式的共有數(shù)據(jù)"
        elif choice == "no":
            df = compare_result["b_common"]
            images = compare_result["b_common_images"]
            title = "保存按B表格格式的共有數(shù)據(jù)"
        else:
            return
        
        self.export_with_images(df, images, title)
    
    # ========== 表格整理功能(修復(fù):處理圖片) ==========
    def update_clean_key_columns(self):
        """更新整理功能的關(guān)鍵列下拉框"""
        if clean_file_data["sheets"] and self.clean_sheet_combobox.get():
            sheet = self.clean_sheet_combobox.get()
            cols = clean_file_data["data"][sheet].columns.tolist()
            self.clean_key_col_combobox.config(state="normal", values=cols)
            self.clean_key_col_combobox.current(0)
    
    def clean_table_task(self):
        """表格整理任務(wù)(修復(fù):合并數(shù)據(jù)+保留圖片)"""
        global cleaned_table_result, cleaned_table_images
        try:
            # 獲取配置
            sheet = self.clean_sheet_combobox.get()
            key_col = self.clean_key_col_combobox.get()
            df = clean_file_data["data"][sheet].copy()
            orig_images = clean_file_data["images"].get(sheet, [])
            
            # 進(jìn)度條初始化
            self.update_progress(0)
            time.sleep(0.1)
            
            # 預(yù)處理
            self.update_progress(10)
            df = df.fillna("")
            
            # 核心整理邏輯
            self.update_progress(20)
            cleaned_rows = []
            current_row = None
            orig_to_new_row = {}  # 原df行號(hào) → 新df行號(hào)映射
            new_row_idx = 0
            
            total_rows = len(df)
            for idx, row in df.iterrows():
                # 更新進(jìn)度
                progress = 20 + (idx / total_rows) * 70
                self.update_progress(progress)
                
                # 關(guān)鍵列非空 = 新行開始
                if str(row[key_col]).strip() != "":
                    if current_row is not None:
                        cleaned_rows.append(current_row)
                        new_row_idx += 1
                    current_row = row.to_dict()
                    orig_to_new_row[idx] = new_row_idx
                else:
                    # 補(bǔ)充到當(dāng)前行
                    if current_row is not None:
                        for col in df.columns:
                            if str(row[col]).strip() != "" and str(current_row[col]).strip() == "":
                                current_row[col] = row[col]
                        orig_to_new_row[idx] = new_row_idx
            
            # 保存最后一行
            if current_row is not None:
                cleaned_rows.append(current_row)
                new_row_idx += 1
            
            # 轉(zhuǎn)換為DataFrame
            self.update_progress(90)
            cleaned_table_result = pd.DataFrame(cleaned_rows)
            
            # 處理圖片(映射到新行號(hào))
            cleaned_table_images = []
            for img, orig_row, col in orig_images:
                orig_df_row = orig_row - 2  # Excel行 → df行號(hào)
                if orig_df_row in orig_to_new_row:
                    # 新Excel行號(hào) = 新df行號(hào) + 2(行1是表頭)
                    new_excel_row = orig_to_new_row[orig_df_row] + 2
                    cleaned_table_images.append((img, new_excel_row, col))
            
            # 完成進(jìn)度
            self.update_progress(100)
            
            # 啟用導(dǎo)出按鈕
            self.export_clean_btn.config(state="normal")
            
            messagebox.showinfo("整理完成", 
                                f"表格整理成功!\n原行數(shù):{len(df)} | 整理后行數(shù):{len(cleaned_table_result)}\n"
                                f"原圖片數(shù):{len(orig_images)} | 整理后圖片數(shù):{len(cleaned_table_images)}")
        
        except Exception as e:
            messagebox.showerror("整理失敗", f"表格整理出錯(cuò):{str(e)}")
            self.update_progress(0)
    
    def start_clean_table(self):
        """啟動(dòng)表格整理"""
        if not self.clean_key_col_combobox.get():
            messagebox.showwarning("提示", "請(qǐng)選擇新行判斷列!")
            return
        
        self.clean_btn.config(state="disabled")
        self.export_clean_btn.config(state="disabled")
        
        clean_thread = threading.Thread(target=self.clean_table_task)
        clean_thread.daemon = True
        clean_thread.start()
    
    def export_cleaned_table(self):
        """導(dǎo)出整理后的表格(修復(fù):保留圖片)"""
        global cleaned_table_result, cleaned_table_images
        if cleaned_table_result is None:
            messagebox.showwarning("提示", "暫無整理后的數(shù)據(jù)!")
            return
        
        self.export_with_images(cleaned_table_result, cleaned_table_images, "保存整理后的表格")

if __name__ == "__main__":
    root = tk.Tk()
    # 解決tkinter中文亂碼(Windows)
    try:
        root.option_add("*Font", "SimHei 9")
    except:
        pass
    
    app = TableCompareApp(root)
    root.mainloop()

以上就是基于Python+Tkinter開發(fā)一個(gè)表格比對(duì)和&整理工具的詳細(xì)內(nèi)容,更多關(guān)于Python Tkinter表格對(duì)比和整理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python3 判斷列表是一個(gè)空列表的方法

    python3 判斷列表是一個(gè)空列表的方法

    今天小編就為大家分享一篇python3 判斷列表是一個(gè)空列表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Python在Excel單元格中應(yīng)用多種字體樣式的代碼示例

    Python在Excel單元格中應(yīng)用多種字體樣式的代碼示例

    文在數(shù)據(jù)處理和報(bào)表生成場(chǎng)景中,Excel 文件的格式設(shè)置至關(guān)重要,合理的字體格式不僅能提升表格的可讀性,還能突出關(guān)鍵數(shù)據(jù),本文將詳細(xì)介紹如何使用免費(fèi)庫Free Spire.XLS for Python,在 Excel 單元格中靈活應(yīng)用多種字體格式,需要的朋友可以參考下
    2025-05-05
  • 打包Python代碼的常用方法小結(jié)

    打包Python代碼的常用方法小結(jié)

    Python是一門強(qiáng)大的編程語言,但在將Python代碼分享給其他人時(shí),讓他們安裝Python解釋器并運(yùn)行腳本可能有點(diǎn)繁瑣,這時(shí),將Python代碼打包成可執(zhí)行的應(yīng)用程序(.exe)可以大大簡(jiǎn)化這個(gè)過程,本文將介紹幾種常用的方法,輕松地將Python代碼變成獨(dú)立的可執(zhí)行文件
    2023-11-11
  • 關(guān)于python爬蟲的原理解析

    關(guān)于python爬蟲的原理解析

    這篇文章主要介紹了python爬蟲原理,今天我們要向大家詳細(xì)解說python爬蟲原理,什么是python爬蟲,python爬蟲工作的基本流程是什么等內(nèi)容,希望對(duì)這正在進(jìn)行python爬蟲學(xué)習(xí)的同學(xué)有所幫助
    2023-07-07
  • Python實(shí)現(xiàn)圖片轉(zhuǎn)字符畫的示例代碼

    Python實(shí)現(xiàn)圖片轉(zhuǎn)字符畫的示例代碼

    本篇文章主要介紹了Python實(shí)現(xiàn)圖片轉(zhuǎn)字符畫的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • python 實(shí)現(xiàn)簡(jiǎn)單的吃豆人游戲

    python 實(shí)現(xiàn)簡(jiǎn)單的吃豆人游戲

    這篇文章主要介紹了python 如何實(shí)現(xiàn)簡(jiǎn)單的吃豆人游戲,幫助大家更好的理解和學(xué)習(xí)使用python制作游戲,感興趣的朋友可以了解下
    2021-04-04
  • Python requests模塊用法詳解

    Python requests模塊用法詳解

    這篇文章主要介紹了Python requests模塊用法,Python內(nèi)置了requests模塊,該模塊主要用來發(fā)送HTTP請(qǐng)求,requests模塊比urllib模塊更簡(jiǎn)潔
    2023-02-02
  • Python疫情確診折線圖實(shí)現(xiàn)數(shù)據(jù)可視化實(shí)例詳解

    Python疫情確診折線圖實(shí)現(xiàn)數(shù)據(jù)可視化實(shí)例詳解

    數(shù)據(jù)可視化是指用圖形或表格的方式來呈現(xiàn)數(shù)據(jù)。圖表能夠清楚地呈現(xiàn)數(shù)據(jù)性質(zhì),?以及數(shù)據(jù)間或?qū)傩蚤g的關(guān)系,可以輕易地讓人看圖釋義。用戶通過探索圖(Exploratory?Graph)可以了解數(shù)據(jù)的特性、尋找數(shù)據(jù)的趨勢(shì)、降低數(shù)據(jù)的理解門檻
    2022-09-09
  • Python爬蟲之獲取心知天氣API實(shí)時(shí)天氣數(shù)據(jù)并彈窗提醒

    Python爬蟲之獲取心知天氣API實(shí)時(shí)天氣數(shù)據(jù)并彈窗提醒

    今天我們來學(xué)習(xí)如何獲取心知天氣API實(shí)時(shí)天氣數(shù)據(jù),制作彈窗提醒,并設(shè)置成自啟動(dòng)項(xiàng)目.文中有非常詳細(xì)的代碼示例及介紹,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • Python mplfinance庫繪制金融圖表實(shí)現(xiàn)數(shù)據(jù)可視化實(shí)例探究

    Python mplfinance庫繪制金融圖表實(shí)現(xiàn)數(shù)據(jù)可視化實(shí)例探究

    mplfinance(Matplotlib Finance),它是基于Matplotlib的庫,專門用于創(chuàng)建金融圖表和交互式金融數(shù)據(jù)可視化,本文將深入介紹?mplfinance,包括其基本概念、功能特性以及如何使用示例代碼創(chuàng)建各種金融圖表
    2024-01-01

最新評(píng)論

翼城县| 文安县| 留坝县| 澄迈县| 拜城县| 卓尼县| 云浮市| 姜堰市| 潜江市| 邯郸市| 巨野县| 禹州市| 鄱阳县| 肇庆市| 隆德县| 二连浩特市| 星子县| 萨迦县| 宁安市| 永康市| 四川省| 济阳县| 慈利县| 齐齐哈尔市| 漳州市| 沅江市| 上虞市| 浪卡子县| 米易县| 和田县| 金门县| 高碑店市| 馆陶县| 磴口县| 永安市| 临沭县| 丰宁| 合江县| 乌兰察布市| 梁平县| 兴安县|