使用Python+openpyxl實(shí)現(xiàn)周報(bào)數(shù)據(jù)自動(dòng)化的操作過(guò)程
背景:被周報(bào)折磨的每個(gè)周一
我目前在一家電商公司負(fù)責(zé)部分業(yè)務(wù)的數(shù)據(jù)支持。我們團(tuán)隊(duì)每周一上午都要出一份銷(xiāo)售周報(bào),數(shù)據(jù)源是運(yùn)營(yíng)同事從后臺(tái)導(dǎo)出的十幾個(gè)Excel文件,每個(gè)文件對(duì)應(yīng)一個(gè)銷(xiāo)售渠道,比如天貓、京東、抖音等等。
我的任務(wù)就是把這些文件里的數(shù)據(jù)匯總到一張總表里,然后做一些簡(jiǎn)單的計(jì)算,比如各渠道銷(xiāo)售額占比、環(huán)比增長(zhǎng)等。聽(tīng)起來(lái)不復(fù)雜,對(duì)吧?但實(shí)際做起來(lái)特別磨人。每個(gè)文件的格式雖然大體一致,但總有細(xì)微差別:有的表頭在第二行,有的在第三行;有的“銷(xiāo)售額”列叫“GMV”;最頭疼的是,有些文件里為了美觀,用了大量的合并單元格。
手動(dòng)操作流程是這樣的:打開(kāi)第一個(gè)文件,找到數(shù)據(jù)區(qū)域,復(fù)制,粘貼到總表;打開(kāi)第二個(gè)文件,發(fā)現(xiàn)表頭對(duì)不上,得手動(dòng)調(diào)整列順序;再打開(kāi)第三個(gè),遇到合并單元格,復(fù)制過(guò)來(lái)格式全亂了……一套流程下來(lái),順利的話也要一個(gè)半小時(shí),要是中途分心貼錯(cuò)了行,又得從頭檢查。每個(gè)周一上午,我就像個(gè)沒(méi)有感情的“Ctrl+C/V”機(jī)器。
我忍了三個(gè)月,終于在一個(gè)數(shù)據(jù)出錯(cuò)被領(lǐng)導(dǎo)點(diǎn)出后下定決心:必須用Python把這個(gè)過(guò)程自動(dòng)化,把時(shí)間還給更有價(jià)值的分析工作。
問(wèn)題分析:為什么不是pandas?
一開(kāi)始,我理所當(dāng)然地想到了pandas。pd.read_excel()和df.to_excel()多簡(jiǎn)單啊。我快速寫(xiě)了個(gè)腳本:
import pandas as pd
import os
all_data = []
folder_path = './sales_reports'
for file in os.listdir(folder_path):
if file.endswith('.xlsx'):
df = pd.read_excel(os.path.join(folder_path, file))
all_data.append(df)
result = pd.concat(all_data, ignore_index=True)
result.to_excel('weekly_summary.xlsx', index=False)
跑了一下,直接報(bào)錯(cuò),而且問(wèn)題一大堆:
- 表頭位置不一致:
pandas默認(rèn)把第一行當(dāng)表頭,但有的文件第一行是標(biāo)題“XX渠道銷(xiāo)售數(shù)據(jù)”,第二行才是真正的列名。導(dǎo)致讀進(jìn)來(lái)的DataFrame列名亂七八糟。 - 合并單元格災(zāi)難:
pandas會(huì)直接把合并單元格的值放在左上角單元格,其他位置變成NaN。當(dāng)我按行復(fù)制時(shí),很多關(guān)鍵數(shù)據(jù)就丟失了。 - 格式丟失:我需要保留原文件中的數(shù)字格式(比如金額的千位分隔符)、字體顏色(標(biāo)紅的下滑數(shù)據(jù))等,
pandas完全做不到。 - 寫(xiě)入新問(wèn)題:用
pandas生成的Excel,有時(shí)候列寬異常,還得手動(dòng)調(diào)整,并沒(méi)有完全“自動(dòng)化”。
我意識(shí)到,pandas適合處理“純數(shù)據(jù)”,但對(duì)于這種需要保持原有格式、結(jié)構(gòu)不那么規(guī)范的Excel文件,有點(diǎn)力不從心。我需要一個(gè)能更精細(xì)操作Excel單元格的庫(kù)。
核心實(shí)現(xiàn):選擇openpyxl與設(shè)計(jì)流程
搜索之后,我鎖定了openpyxl。它是一個(gè)專(zhuān)門(mén)讀寫(xiě).xlsx格式的庫(kù),可以精確到單元格級(jí)別進(jìn)行讀寫(xiě),還能處理樣式。雖然不能讀老舊的.xls格式,但我們公司早就全面升級(jí)了,所以沒(méi)問(wèn)題。
我的自動(dòng)化腳本需要完成以下幾個(gè)核心步驟:
- 智能定位數(shù)據(jù):自動(dòng)跳過(guò)表頭,找到每個(gè)文件數(shù)據(jù)開(kāi)始的真實(shí)位置。
- 破解合并單元格:將合并區(qū)域的值“填充”到每一個(gè)單元格,保證數(shù)據(jù)不丟失。
- 統(tǒng)一列映射:建立渠道列名與總表標(biāo)準(zhǔn)列名的映射關(guān)系,比如把“GMV”、“銷(xiāo)售金額”都映射到“銷(xiāo)售額”。
- 帶格式寫(xiě)入:將數(shù)據(jù)連同基本的格式(字體、邊框、數(shù)字格式)寫(xiě)入總表。
- 簡(jiǎn)單計(jì)算:在總表中自動(dòng)計(jì)算合計(jì)、占比等。
下面我就分步拆解實(shí)現(xiàn)過(guò)程。
1. 智能定位數(shù)據(jù)起始行
這是第一個(gè)關(guān)鍵點(diǎn)。我觀察發(fā)現(xiàn),所有有效數(shù)據(jù)的表頭行都包含“日期”這個(gè)關(guān)鍵詞。所以,我的策略是:遍歷文件的前10行(足夠覆蓋所有情況),找到第一個(gè)包含“日期”的單元格所在的行,那一行就是表頭,下一行就是數(shù)據(jù)起始行。
from openpyxl import load_workbook
def find_data_start_row(ws, header_keyword="日期"):
"""
在工作表中查找包含指定關(guān)鍵詞的表頭行
返回?cái)?shù)據(jù)起始行號(hào)(即表頭行號(hào)+1)
"""
# 通常數(shù)據(jù)不會(huì)超過(guò)前20行開(kāi)始
for row in ws.iter_rows(min_row=1, max_row=20, max_col=10):
for cell in row:
if cell.value and header_keyword in str(cell.value):
# 找到關(guān)鍵詞,返回下一行作為數(shù)據(jù)開(kāi)始
return cell.row + 1
# 如果沒(méi)找到,默認(rèn)從第2行開(kāi)始(假設(shè)第一行是表頭)
return 2
這里有個(gè)坑:cell.value可能是None,直接進(jìn)行in判斷會(huì)報(bào)錯(cuò),所以必須先判斷cell.value是否存在,再轉(zhuǎn)換成字符串進(jìn)行查找。
2. 破解合并單元格并建立列映射
這是最棘手的部分。openpyxl的worksheet.merged_cells.ranges屬性可以獲取所有合并單元格的范圍。我的思路是:先記錄下每個(gè)合并范圍的值,然后在讀取數(shù)據(jù)時(shí),如果遇到屬于合并范圍的單元格,就使用記錄的值。
同時(shí),我需要建立一個(gè)列名映射字典。我手動(dòng)定義了一個(gè)標(biāo)準(zhǔn)列名列表,然后根據(jù)每個(gè)文件表頭行的內(nèi)容進(jìn)行模糊匹配。
def get_column_mapping(ws, header_row_idx):
"""
根據(jù)表頭行,建立列索引到標(biāo)準(zhǔn)列名的映射。
例如:{1: '日期', 2: '銷(xiāo)售額', ...}
"""
# 標(biāo)準(zhǔn)列名(總表使用的)
standard_headers = ['日期', '渠道', '商品ID', '商品名稱(chēng)', '銷(xiāo)售額', '訂單量']
mapping = {}
header_row = ws[header_row_idx]
for cell in header_row:
if cell.value:
header_text = str(cell.value).strip()
# 模糊匹配:如果標(biāo)準(zhǔn)列名是當(dāng)前表頭的一部分,或反之,則匹配
for std_header in standard_headers:
if std_header in header_text or header_text in std_header:
mapping[cell.column] = std_header # cell.column是列索引,如1,2,3
break # 匹配到一個(gè)就跳出內(nèi)層循環(huán)
return mapping
注意這個(gè)細(xì)節(jié):cell.column返回的是從1開(kāi)始的列索引(整數(shù)),而不是字母。這比用column_index_from_string轉(zhuǎn)換更方便。
處理合并單元格的讀取邏輯,我把它整合到了遍歷數(shù)據(jù)的函數(shù)里:
def read_sheet_data(ws, data_start_row, col_mapping, merged_cell_values):
"""
從指定行開(kāi)始讀取數(shù)據(jù),應(yīng)用列映射,并處理合并單元格值。
返回一個(gè)列表,每個(gè)元素是一行數(shù)據(jù)的字典。
"""
data = []
# 獲取最大行和最大列(有數(shù)據(jù)的區(qū)域)
max_row = ws.max_row
max_column = ws.max_column
for row in range(data_start_row, max_row + 1):
row_data = {v: None for v in col_mapping.values()} # 用標(biāo)準(zhǔn)列名初始化字典
for col_idx, std_header in col_mapping.items():
cell = ws.cell(row=row, column=col_idx)
cell_value = cell.value
# 關(guān)鍵!處理合并單元格:如果當(dāng)前單元格在合并范圍內(nèi),則取合并區(qū)域的值
for merged_range in merged_cell_values:
if cell.coordinate in merged_range:
cell_value = merged_cell_values[merged_range]
break
row_data[std_header] = cell_value
# 如果一行數(shù)據(jù)全為空,則跳過(guò)(可能是末尾的空行)
if any(row_data.values()):
# 補(bǔ)充渠道信息(可以從文件名解析,這里簡(jiǎn)化處理)
row_data['渠道'] = os.path.basename(ws.parent.filepath).split('_')[0]
data.append(row_data)
return data
3. 帶格式寫(xiě)入總表
數(shù)據(jù)都讀出來(lái)并統(tǒng)一格式后,寫(xiě)入就相對(duì)簡(jiǎn)單了。我用openpyxl創(chuàng)建一個(gè)新的工作簿,先寫(xiě)入標(biāo)準(zhǔn)表頭,并設(shè)置簡(jiǎn)單的樣式(加粗、居中、背景色)。然后逐行寫(xiě)入數(shù)據(jù),給數(shù)值列加上千位分隔符的數(shù)字格式。
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from openpyxl.utils import get_column_letter
def write_summary(data_list, output_path='周報(bào)匯總.xlsx'):
"""將整理好的數(shù)據(jù)列表寫(xiě)入新的Excel文件"""
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "銷(xiāo)售周報(bào)匯總"
# 定義標(biāo)準(zhǔn)表頭
headers = ['日期', '渠道', '商品ID', '商品名稱(chēng)', '銷(xiāo)售額', '訂單量']
# 設(shè)置表頭樣式
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
alignment = Alignment(horizontal="center", vertical="center")
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'),
top=Side(style='thin'), bottom=Side(style='thin'))
# 寫(xiě)入表頭
for col_idx, header in enumerate(headers, start=1):
cell = ws.cell(row=1, column=col_idx, value=header)
cell.font = header_font
cell.fill = header_fill
cell.alignment = alignment
cell.border = thin_border
# 寫(xiě)入數(shù)據(jù)
row_idx = 2
for row_data in data_list:
for col_idx, header in enumerate(headers, start=1):
cell = ws.cell(row=row_idx, column=col_idx, value=row_data.get(header))
cell.border = thin_border
# 給銷(xiāo)售額和訂單量列設(shè)置數(shù)字格式
if header in ['銷(xiāo)售額', '訂單量'] and isinstance(cell.value, (int, float)):
if header == '銷(xiāo)售額':
cell.number_format = '#,##0.00' # 千位分隔符,兩位小數(shù)
else:
cell.number_format = '#,##0'
row_idx += 1
# 自動(dòng)調(diào)整列寬(近似)
for col in ws.columns:
max_length = 0
column_letter = get_column_letter(col[0].column)
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 50) # 設(shè)置一個(gè)最大寬度
ws.column_dimensions[column_letter].width = adjusted_width
wb.save(output_path)
print(f"匯總完成!文件已保存至:{output_path}")
這里有個(gè)坑:openpyxl的自動(dòng)調(diào)整列寬ws.column_dimensions[column_letter].bestFit并不總是可靠,我采用了計(jì)算每列最大字符長(zhǎng)度的方法,雖然簡(jiǎn)單但效果不錯(cuò)。注意要捕獲str(cell.value)的異常,因?yàn)?code>cell.value可能是None。
4. 串聯(lián)主流程與簡(jiǎn)單計(jì)算
最后,我把所有功能串聯(lián)起來(lái),并在寫(xiě)入數(shù)據(jù)后,在總表末尾添加兩行:一行計(jì)算各渠道銷(xiāo)售總額,一行計(jì)算占比。
# 在主函數(shù)中,讀取所有文件數(shù)據(jù)后
all_data = []
for file_path in excel_files:
wb = load_workbook(file_path, data_only=True) # data_only=True只讀值,不讀公式
ws = wb.active
ws.filepath = file_path # 給ws對(duì)象加個(gè)屬性,方便后面取文件名
# 找到表頭行和數(shù)據(jù)起始行
header_row_idx = find_data_start_row(ws) - 1
data_start_row = header_row_idx + 1
# 獲取列映射
col_mapping = get_column_mapping(ws, header_row_idx)
if not col_mapping:
print(f"警告:在文件 {file_path} 中未找到匹配的表頭,跳過(guò)。")
continue
# 預(yù)處理合并單元格的值
merged_cell_values = {}
for merged_range in ws.merged_cells.ranges:
# 獲取合并區(qū)域左上角單元格的值
top_left_cell = ws[merged_range.min_row][merged_range.min_col - 1] # 注意索引轉(zhuǎn)換
merged_cell_values[merged_range] = top_left_cell.value
# 讀取數(shù)據(jù)
sheet_data = read_sheet_data(ws, data_start_row, col_mapping, merged_cell_values)
all_data.extend(sheet_data)
# 寫(xiě)入?yún)R總文件
write_summary(all_data)
# 在write_summary函數(shù)內(nèi)部,數(shù)據(jù)寫(xiě)入后,可以添加匯總行
# ... 數(shù)據(jù)寫(xiě)入循環(huán)之后 ...
summary_row = row_idx + 1
ws.cell(row=summary_row, column=4, value="渠道總計(jì)").font = Font(bold=True)
# 使用公式計(jì)算每個(gè)渠道的銷(xiāo)售額總和(假設(shè)渠道名列是B,銷(xiāo)售額列是E)
# 這里簡(jiǎn)化,實(shí)際可以按渠道分組計(jì)算
ws.cell(row=summary_row, column=5, value=f"=SUMIF(B2:B{row_idx}, B{summary_row}, E2:E{row_idx})")
完整代碼
"""
Excel銷(xiāo)售周報(bào)自動(dòng)化匯總腳本
作者:實(shí)戰(zhàn)踩坑記錄
功能:自動(dòng)讀取多個(gè)渠道銷(xiāo)售Excel,統(tǒng)一格式后匯總至一個(gè)文件。
"""
import os
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from openpyxl.utils import get_column_letter
def find_data_start_row(ws, header_keyword="日期"):
"""定位數(shù)據(jù)起始行"""
for row in ws.iter_rows(min_row=1, max_row=20, max_col=10):
for cell in row:
if cell.value and header_keyword in str(cell.value):
return cell.row + 1
return 2
def get_column_mapping(ws, header_row_idx):
"""建立列索引到標(biāo)準(zhǔn)列名的映射"""
standard_headers = ['日期', '渠道', '商品ID', '商品名稱(chēng)', '銷(xiāo)售額', '訂單量']
mapping = {}
header_row = ws[header_row_idx]
for cell in header_row:
if cell.value:
header_text = str(cell.value).strip()
for std_header in standard_headers:
if std_header in header_text or header_text in std_header:
mapping[cell.column] = std_header
break
return mapping
def read_sheet_data(ws, data_start_row, col_mapping, merged_cell_values):
"""讀取單文件數(shù)據(jù),處理合并單元格"""
data = []
max_row = ws.max_row
for row in range(data_start_row, max_row + 1):
row_data = {v: None for v in col_mapping.values()}
for col_idx, std_header in col_mapping.items():
cell = ws.cell(row=row, column=col_idx)
cell_value = cell.value
# 處理合并單元格
for merged_range, merged_value in merged_cell_values.items():
if cell.coordinate in merged_range:
cell_value = merged_value
break
row_data[std_header] = cell_value
if any(row_data.values()):
# 簡(jiǎn)單從文件名提取渠道名,可根據(jù)實(shí)際情況修改
filename = os.path.basename(ws.parent.filepath)
channel = filename.split('_')[0] if '_' in filename else filename.replace('.xlsx', '')
row_data['渠道'] = channel
data.append(row_data)
return data
def write_summary(data_list, output_path='周報(bào)匯總.xlsx'):
"""寫(xiě)入?yún)R總文件并添加格式"""
wb = Workbook()
ws = wb.active
ws.title = "銷(xiāo)售周報(bào)匯總"
headers = ['日期', '渠道', '商品ID', '商品名稱(chēng)', '銷(xiāo)售額', '訂單量']
# 樣式定義
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
align_center = Alignment(horizontal="center", vertical="center")
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'),
top=Side(style='thin'), bottom=Side(style='thin'))
# 寫(xiě)表頭
for col_idx, header in enumerate(headers, start=1):
cell = ws.cell(row=1, column=col_idx, value=header)
cell.font = header_font
cell.fill = header_fill
cell.alignment = align_center
cell.border = thin_border
# 寫(xiě)數(shù)據(jù)
row_idx = 2
for row_data in data_list:
for col_idx, header in enumerate(headers, start=1):
cell = ws.cell(row=row_idx, column=col_idx, value=row_data.get(header))
cell.border = thin_border
if header in ['銷(xiāo)售額', '訂單量'] and isinstance(cell.value, (int, float)):
cell.number_format = '#,##0.00' if header == '銷(xiāo)售額' else '#,##0'
row_idx += 1
# 調(diào)整列寬
for col in ws.columns:
max_len = 0
col_letter = get_column_letter(col[0].column)
for cell in col:
try:
cell_len = len(str(cell.value))
if cell_len > max_len:
max_len = cell_len
except:
pass
adjusted_width = min(max_len + 2, 50)
ws.column_dimensions[col_letter].width = adjusted_width
wb.save(output_path)
print(f"? 匯總完成!文件已保存至:{output_path}")
def main():
# 配置路徑
reports_folder = './sales_reports' # 存放所有渠道Excel文件的文件夾
output_file = './周報(bào)匯總.xlsx'
if not os.path.exists(reports_folder):
print(f"錯(cuò)誤:文件夾 '{reports_folder}' 不存在。")
return
all_data = []
excel_files = [os.path.join(reports_folder, f) for f in os.listdir(reports_folder)
if f.endswith(('.xlsx', '.xlsm'))]
if not excel_files:
print("未找到Excel文件。")
return
for file_path in excel_files:
print(f"正在處理:{os.path.basename(file_path)}")
try:
wb = load_workbook(file_path, data_only=True)
ws = wb.active
ws.parent.filepath = file_path # 臨時(shí)存儲(chǔ)路徑
header_row_idx = find_data_start_row(ws) - 1
data_start_row = header_row_idx + 1
col_mapping = get_column_mapping(ws, header_row_idx)
if not col_mapping:
print(f" ?? 跳過(guò),未識(shí)別到表頭。")
continue
# 處理合并單元格
merged_values = {}
for merged_range in ws.merged_cells.ranges:
top_left_cell = ws[merged_range.min_row][merged_range.min_col - 1]
merged_values[merged_range] = top_left_cell.value
sheet_data = read_sheet_data(ws, data_start_row, col_mapping, merged_values)
all_data.extend(sheet_data)
print(f" ? 讀取到 {len(sheet_data)} 行數(shù)據(jù)。")
except Exception as e:
print(f" ? 處理文件時(shí)出錯(cuò):{e}")
if all_data:
write_summary(all_data, output_file)
print(f"總計(jì)處理 {len(excel_files)} 個(gè)文件,合并 {len(all_data)} 行數(shù)據(jù)。")
else:
print("未讀取到任何有效數(shù)據(jù)。")
if __name__ == "__main__":
main()
踩坑記錄
data_only=True的誤解:一開(kāi)始我沒(méi)加這個(gè)參數(shù),結(jié)果有些單元格值是公式(如=SUM(A1:A10)),讀出來(lái)就是公式字符串本身,而不是計(jì)算結(jié)果。加上data_only=True后,openpyxl會(huì)讀取上次Excel保存時(shí)計(jì)算好的值。但要注意,如果文件從未被Excel計(jì)算保存過(guò),讀出的公式值可能是None。- 合并單元格的坐標(biāo)判斷:
cell.coordinate返回的是字符串(如'A1'),而merged_range是一個(gè)CellRange對(duì)象。我最初直接用cell.coordinate == merged_range,永遠(yuǎn)為False。正確做法是使用cell.coordinate in merged_range,CellRange對(duì)象支持in操作符來(lái)判斷坐標(biāo)是否在其范圍內(nèi)。 - 列索引與列字母的混淆:
openpyxl中,cell.column返回整數(shù)索引(1-based),cell.column_letter返回字母。在遍歷和存儲(chǔ)映射關(guān)系時(shí),用整數(shù)索引更不容易出錯(cuò)。但在設(shè)置列寬ws.column_dimensions[column_letter]時(shí),又必須用字母。這個(gè)轉(zhuǎn)換需要用get_column_letter()函數(shù)。 - 中文路徑或文件名報(bào)錯(cuò):在Windows上,如果文件路徑或工作表名稱(chēng)包含中文,有時(shí)會(huì)報(bào)編碼相關(guān)的錯(cuò)誤。一個(gè)穩(wěn)妥的做法是使用
os.path模塊來(lái)構(gòu)建路徑,并確保Python腳本文件本身保存為UTF-8編碼。如果問(wèn)題依舊,可以嘗試在文件路徑字符串前加r(原始字符串)防止轉(zhuǎn)義。
小結(jié)
這個(gè)自動(dòng)化腳本把我每周一上午的“體力活”壓縮到了3分鐘以?xún)?nèi),而且完全避免了手動(dòng)操作可能帶來(lái)的錯(cuò)誤。核心收獲是:處理非標(biāo)準(zhǔn)格式的Excel文件,openpyxl這種單元格級(jí)操作的庫(kù)比pandas更靈活、更強(qiáng)大。下一步可以考慮加入郵件自動(dòng)發(fā)送功能,或者用PyInstaller打包成可執(zhí)行文件,分享給不會(huì)編程的同事使用。
以上就是使用Python+openpyxl實(shí)現(xiàn)周報(bào)數(shù)據(jù)自動(dòng)化的操作過(guò)程的詳細(xì)內(nèi)容,更多關(guān)于Python openpyxl周報(bào)數(shù)據(jù)自動(dòng)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)多線程暴力破解登陸路由器功能代碼分享
這篇文章主要介紹了python實(shí)現(xiàn)多線程暴力破解登陸路由器功能代碼分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-01-01
如何使用yolov5輸出檢測(cè)到的目標(biāo)坐標(biāo)信息
YOLOv5是一系列在 COCO 數(shù)據(jù)集上預(yù)訓(xùn)練的對(duì)象檢測(cè)架構(gòu)和模型,下面這篇文章主要給大家介紹了關(guān)于如何使用yolov5輸出檢測(cè)到的目標(biāo)坐標(biāo)信息的相關(guān)資料,需要的朋友可以參考下2022-03-03
關(guān)于SSD目標(biāo)檢測(cè)模型的人臉口罩識(shí)別
這篇文章主要介紹了關(guān)于SSD目標(biāo)檢測(cè)模型的人臉口罩識(shí)別問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
Python實(shí)現(xiàn)3行代碼解簡(jiǎn)單的一元一次方程
這篇文章主要介紹了Python實(shí)現(xiàn)3行代碼解簡(jiǎn)單的一元一次方程,很適合Python初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下2014-08-08
基于python+selenium的二次封裝的實(shí)現(xiàn)
這篇文章主要介紹了基于python+selenium的二次封裝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
python歐拉角和旋轉(zhuǎn)矩陣變換的實(shí)現(xiàn)示例
在計(jì)算機(jī)圖形學(xué)中,歐拉角和旋轉(zhuǎn)矩陣是描述物體旋轉(zhuǎn)的常用方法,本文主要介紹了python歐拉角和旋轉(zhuǎn)矩陣變換的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03

