第2章 从工具认知到业务落地:Excel、Python与ChatGPT协同驱动的数据分析实践导论
摘要:数据分析工具协同应用实践 本章探讨了Excel、Python和ChatGPT在数据分析中的协同应用。核心观点认为,数据分析的本质是解决业务问题而非单纯使用工具。现代数据分析面临效率低、难复现和解释浅三大挑战,需要通过工具协同构建完整分析链路:Excel负责快速查看与展示,Python处理批量计算与自动化,ChatGPT辅助问题拆解与代码生成。文章强调分析应遵循"描述-诊断-预测-决
第2章 从工具认知到业务落地:Excel、Python与ChatGPT协同驱动的数据分析实践导论
数据分析这项工作,看上去是在处理数字,实际上是在回答业务问题。门店销量为什么下降,客户为什么不复购,库存为什么积压,活动为什么没有带来预期增长,这些问题的背后都离不开数据。很多人一开始接触数据分析时,往往把注意力放在公式、函数、代码或者图表上,但真正决定分析质量的,往往不是工具本身,而是三个更底层的能力:能不能把问题说清楚,能不能把数据整理干净,能不能把结果转化为行动。
在实际工作中,Excel、Python和ChatGPT并不是互相替代的关系,而是互相补位的关系。Excel适合快速查看、核对、汇报和轻量分析;Python适合批量处理、自动化计算和复杂建模;ChatGPT适合帮助人梳理问题、生成初版方案、改写代码、解释逻辑和提升沟通效率。三者组合起来,就不再是单纯的“会做表”,而是形成了一套更完整的数据分析工作流。
本章围绕这条主线展开:先讲工具协同背后的分析逻辑,再讲Excel与Python如何分工,再讲ChatGPT怎样参与到问题定义、代码生成和分析表达中,最后落到提示词设计和学习路径上。内容不仅讲概念,也穿插零售经营、客户运营、销售复盘等商业案例,并配套可运行的Python代码,帮助读者把理论和实务真正接起来。
2.1 本章导读:为什么数据分析越来越强调工具协同
过去不少企业做数据分析,依赖的是“一个熟练用Excel的人”。这种方式在数据量小、业务节奏慢的时候还能应付,但当企业的门店、商品、客户、订单、渠道同时增长时,人工复制、粘贴、筛选、汇总很快就会出现三个问题。
第一,效率跟不上。
如果每天要汇总二十家门店的数据、清洗几千条订单记录、对比多个时间周期,单靠手工操作不仅慢,而且容易出错。越是重复劳动,越需要自动化。
第二,结果难以复现。
很多人在Excel里做分析时,今天改了一列,明天复制了一块区域,后天又手动修了一些数,最后连自己都不清楚最终结果是怎么来的。这样的分析很难交接,也难以沉淀。
第三,业务解释不够深。
很多报表只能告诉管理者“发生了什么”,却解释不了“为什么会发生”以及“下一步应该怎么做”。这就需要把分析思路、指标体系和业务逻辑一起纳入工作流程。
因此,现代数据分析越来越强调工具协同。简单说,就是让不同工具各做自己最擅长的部分:
工具 最擅长的事 典型场景
Excel 快速查看、手工校验、透视汇总、图表展示 日报、周报、经营会议材料
Python 批量处理、清洗、计算、建模、自动导出 数据预处理、自动报表、预测分析
ChatGPT 问题拆解、提示词设计、代码生成、结果改写 方案草拟、代码辅助、分析说明
从本质上说,工具协同不是为了“显得高级”,而是为了形成一条更稳定的分析链路:
业务问题提出 -> 数据准备 -> 数据清洗 -> 指标计算 -> 结果解释 -> 报告输出 -> 业务动作执行。
谁能把这条链路打通,谁的数据分析能力就更接近真实工作场景。
2.2 Excel与Python结合的数据处理认知
2.2.1 先理解分析工作的底层逻辑
在讲工具之前,先要把数据分析的底层逻辑讲清楚。很多人学了很多函数、很多库,还是做不好分析,根本原因并不是不会操作,而是不知道分析究竟要解决什么。
一个完整的数据分析流程,通常包括以下几个环节:
明确业务问题
例如:最近三个月门店利润下滑,原因是什么?
定义分析目标
是看销售额、毛利、客单价、退货率,还是会员复购率?
识别数据来源
订单表、商品表、门店表、会员表、活动表、库存表。
处理数据质量问题
缺失值、重复值、格式不统一、异常值、时间口径不一致。
建立分析指标
比如销售额、毛利额、毛利率、单店产出、品类贡献率、复购率。
形成分析结论
例如:利润下滑不是因为销量下降,而是因为高毛利商品占比下降,且退货集中发生在两家门店。
转化为业务动作
优化商品结构、调整促销策略、复盘门店执行、强化会员召回。
这七步里,Excel、Python和ChatGPT其实都只是服务工具。真正的核心,是从“问题”走到“行动”。
从分析理论上看,企业常见的数据分析可以分为四类:
描述性分析:发生了什么
例如,本月销售额是多少,哪个门店排名第一。
诊断性分析:为什么发生
例如,销售额下降是因为客流减少,还是客单价下降。
预测性分析:未来可能会怎样
例如,下个月销量可能落在什么区间。
决策性分析:应该怎么做
例如,是否应该减少低毛利品类投放。
初学者最容易犯的错误,是一上来就想做预测,结果连基础数据都没整理好。正确顺序应该是先做描述,再做诊断,然后才考虑预测和决策。
所以,无论后面学的是Excel还是Python,第一原则都不变:
分析不是把表做漂亮,而是把业务问题拆成可以计算、可以验证、可以落地的任务。
2.2.2 用Excel完成日常表格分析与快速校验
Excel之所以在企业里长期稳定存在,不是因为它“简单”,而是因为它特别贴近业务人员的工作方式。一个销售主管、门店经理、采购专员,哪怕不会写代码,也能用Excel看数据、核数据、做汇报。这种低门槛,是Excel最大的价值。
Excel在数据分析中的典型优势,主要体现在五个方面。
一、可视化操作直观
筛选、排序、冻结窗格、条件格式、图表、透视表,几乎都可以通过点击完成。对非技术岗位来说,这种操作方式天然更容易上手。
二、适合小规模、快节奏分析
如果只有几百到几千条数据,Excel完全能胜任。比如门店日报、客服工单汇总、活动报名名单整理、销售员业绩排名,这些都可以快速完成。
三、核对和复查效率高
很多时候,真正耗时间的不是复杂计算,而是确认数据有没有问题。Excel在逐行查看、局部修正、人工标记方面非常方便,适合作为“最终检查台”。
四、透视表特别适合经营复盘
透视表本质上就是一种低门槛聚合分析工具。它可以快速把明细数据转换成“按门店、按品类、按日期、按员工、按区域”的汇总视角。这一点在经营分析中非常实用。
五、适合直接形成汇报材料
管理层看报表,不一定关心脚本是怎么写的,但一定关心结果是否清楚。Excel的图表、格式、颜色、布局天生适合会议材料输出。
不过,Excel也有明显边界。
数据量一大,性能下降明显。
手工步骤多,复用性差。
多人协作时版本容易混乱。
逻辑一复杂,公式维护成本会很高。
过程不透明,难以追溯。
以一个零售连锁企业为例。假设运营经理每天要汇总十家门店的销售表,内容包括销售额、退货单、会员订单、促销订单。刚开始门店少时,用Excel分别粘贴进总表,再做透视表,确实够用。但随着门店扩张到五十家,商品SKU增加到三千个,人工汇总就会出现以下问题:
不同门店字段不一致,有的写“销售金额”,有的写“实收金额”
日期格式混乱,有的是“2025/01/01”,有的是“2025-1-1”
商品名称存在别名,导致透视表统计失真
退货记录有的写成负数,有的单独标记
每天的分析步骤重复,但仍要手工操作
这时就说明:Excel还在发挥价值,但已经不能独立承担全部分析任务了。它更适合作为“前端交互和结果展示工具”,而不应该继续承担大量重复清洗工作。
因此,在企业实际应用中,Excel最合理的位置通常有三个:
作为原始数据收集与人工校验界面
作为分析结果承载与图表展示载体
作为业务人员和技术人员之间的沟通中间层
说得更直白一点,Excel不应该被淘汰,而应该被重新分工。
2.2.3 借助Python建立可复用的数据处理流程
如果说Excel解决的是“看得见、改得动”的问题,那么Python解决的是“做得快、做得稳、做得可重复”的问题。
Python在数据分析中的核心价值,不是“代码更高级”,而是它能把重复工作变成流程,把流程变成资产。今天处理一份表,明天处理十份表,后天处理一百份表,只要规则不变,脚本就能复用。
这背后对应的是现代数据分析非常重要的一个原则:可复现性。
所谓可复现性,简单理解就是同一份数据、同一套逻辑、同一段代码,不管什么时候运行,结果都应该一致。这样的分析才经得起复盘、审计和交接。
在商业场景里,Python尤其适合以下任务:
批量读取多个Excel文件
统一字段名和数据格式
清洗缺失值、重复值、异常值
自动计算KPI指标
多维度分组汇总
自动生成分析结果文件
连接数据库或接口拉取数据
进一步做预测、分类、聚类、推荐等模型任务
下面通过一个可直接运行的零售经营分析案例,说明Python怎样把日常报表工作做成自动化流程。
商业案例:连锁零售门店经营分析自动化
场景设定如下:
某连锁零售企业希望每周自动输出一份经营分析报告,关注以下问题:
总销售额、毛利额、毛利率表现如何
哪些门店贡献更高,哪些门店退货异常
哪些商品品类销量高但利润低
每日销售趋势是否存在明显波动
会员复购率处于什么水平
为了方便演示,下面的代码会先自动生成一份模拟销售数据,再完成清洗、计算、汇总和Excel导出。代码可在 VS Code 中直接运行。
示例代码:使用 pandas 与 openpyxl 自动生成经营分析报告
python
from future import annotations
import random
from datetime import datetime, timedelta
from pathlib import Path
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Alignment
from openpyxl.styles import Font
from openpyxl.styles import PatternFill
def createSampleSalesFile(outputPath: str, rowCount: int = 1200) -> None:
random.seed(42)
storeNames = ["朝阳店", "国贸店", "望京店", "中关村店", "西单店"]
paymentTypes = ["微信", "支付宝", "现金", "银行卡"]
categoryProductMap = {
"饮品": [("美式咖啡", 18), ("拿铁", 24), ("燕麦拿铁", 28), ("柠檬茶", 16)],
"烘焙": [("牛角包", 12), ("芝士面包", 15), ("全麦吐司", 14)],
"轻食": [("鸡胸沙拉", 29), ("金枪鱼三明治", 26), ("酸奶水果杯", 22)],
"周边": [("保温杯", 79), ("帆布袋", 39), ("玻璃杯", 49)]
}
startDate = datetime(2025, 1, 1)
rows = []
for rowIndex in range(1, rowCount + 1):
categoryName = random.choice(list(categoryProductMap.keys()))
productName, basePrice = random.choice(categoryProductMap[categoryName])
quantity = random.randint(1, 5)
unitPrice = round(basePrice * random.uniform(0.95, 1.10), 2)
costPrice = round(unitPrice * random.uniform(0.38, 0.62), 2)
orderDate = startDate + timedelta(days=random.randint(0, 89))
returnedFlag = 1 if random.random() < 0.05 else 0
if random.random() < 0.75:
memberId = f"M{random.randint(1001, 1100)}"
else:
memberId = None
rows.append(
{
"OrderId": f"O{100000 + rowIndex}",
"OrderDate": orderDate.strftime("%Y-%m-%d"),
"StoreName": random.choice(storeNames),
"ProductCategory": categoryName,
"ProductName": productName,
"Quantity": quantity,
"UnitPrice": unitPrice,
"CostPrice": costPrice,
"MemberId": memberId,
"PaymentType": random.choice(paymentTypes),
"ReturnedFlag": returnedFlag
}
)
dataFrame = pd.DataFrame(rows)
if len(dataFrame) >= 6:
dataFrame.loc[2, "UnitPrice"] = None
dataFrame.loc[4, "Quantity"] = "3"
dataFrame.loc[5, "OrderDate"] = "2025/01/09"
dataFrame.to_excel(outputPath, index=False)
class RetailAnalysisEngine:
def __init__(self, sourceFilePath: str) -> None:
self.sourceFilePath = Path(sourceFilePath)
def loadData(self) -> pd.DataFrame:
dataFrame = pd.read_excel(self.sourceFilePath)
return dataFrame
def cleanData(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
workFrame = dataFrame.copy()
workFrame["OrderDate"] = pd.to_datetime(workFrame["OrderDate"], errors="coerce")
workFrame["Quantity"] = pd.to_numeric(workFrame["Quantity"], errors="coerce").fillna(0).astype(int)
workFrame["UnitPrice"] = pd.to_numeric(workFrame["UnitPrice"], errors="coerce")
workFrame["CostPrice"] = pd.to_numeric(workFrame["CostPrice"], errors="coerce")
workFrame["ReturnedFlag"] = pd.to_numeric(workFrame["ReturnedFlag"], errors="coerce").fillna(0).astype(int)
workFrame["UnitPrice"] = workFrame["UnitPrice"].fillna(
workFrame.groupby("ProductCategory")["UnitPrice"].transform("median")
)
workFrame["CostPrice"] = workFrame["CostPrice"].fillna(workFrame["UnitPrice"] * 0.55)
workFrame["MemberId"] = workFrame["MemberId"].fillna("Guest")
workFrame = workFrame.dropna(
subset=["OrderDate", "StoreName", "ProductCategory", "ProductName", "UnitPrice", "CostPrice"]
)
workFrame["SalesAmount"] = workFrame["Quantity"] * workFrame["UnitPrice"]
workFrame["CostAmount"] = workFrame["Quantity"] * workFrame["CostPrice"]
returnMask = workFrame["ReturnedFlag"] == 1
workFrame.loc[returnMask, "SalesAmount"] = workFrame.loc[returnMask, "SalesAmount"] * -1
workFrame.loc[returnMask, "CostAmount"] = workFrame.loc[returnMask, "CostAmount"] * -1
workFrame["GrossProfit"] = workFrame["SalesAmount"] - workFrame["CostAmount"]
workFrame["OrderMonth"] = workFrame["OrderDate"].dt.to_period("M").astype(str)
workFrame["OrderDay"] = workFrame["OrderDate"].dt.date.astype(str)
return workFrame
def buildSummary(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
totalSales = round(dataFrame["SalesAmount"].sum(), 2)
totalProfit = round(dataFrame["GrossProfit"].sum(), 2)
grossMargin = round(totalProfit / totalSales, 4) if totalSales != 0 else 0
orderCount = int(dataFrame["OrderId"].nunique())
avgOrderValue = round(totalSales / orderCount, 2) if orderCount != 0 else 0
memberOrderFrame = (
dataFrame[dataFrame["MemberId"] != "Guest"]
.groupby("MemberId")["OrderId"]
.nunique()
.reset_index(name="OrderCount")
)
memberCount = int(memberOrderFrame["MemberId"].nunique())
repeatMemberCount = int((memberOrderFrame["OrderCount"] >= 2).sum())
repeatRate = round(repeatMemberCount / memberCount, 4) if memberCount != 0 else 0
summaryFrame = pd.DataFrame(
[
{"MetricName": "净销售额", "MetricValue": totalSales},
{"MetricName": "毛利额", "MetricValue": totalProfit},
{"MetricName": "毛利率", "MetricValue": grossMargin},
{"MetricName": "订单数", "MetricValue": orderCount},
{"MetricName": "平均订单金额", "MetricValue": avgOrderValue},
{"MetricName": "会员复购率", "MetricValue": repeatRate}
]
)
return summaryFrame
def buildStoreAnalysis(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
storeFrame = (
dataFrame.groupby("StoreName")
.agg(
NetSales=("SalesAmount", "sum"),
GrossProfit=("GrossProfit", "sum"),
OrderCount=("OrderId", "nunique"),
ReturnCount=("ReturnedFlag", "sum")
)
.reset_index()
)
storeFrame["GrossMargin"] = (
storeFrame["GrossProfit"] / storeFrame["NetSales"].replace(0, pd.NA)
).round(4)
storeFrame["AvgOrderValue"] = (
storeFrame["NetSales"] / storeFrame["OrderCount"].replace(0, pd.NA)
).round(2)
storeFrame = storeFrame.sort_values(by="NetSales", ascending=False)
return storeFrame
def buildCategoryAnalysis(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
categoryFrame = (
dataFrame.groupby("ProductCategory")
.agg(
NetSales=("SalesAmount", "sum"),
GrossProfit=("GrossProfit", "sum"),
Quantity=("Quantity", "sum"),
ReturnCount=("ReturnedFlag", "sum")
)
.reset_index()
)
categoryFrame["GrossMargin"] = (
categoryFrame["GrossProfit"] / categoryFrame["NetSales"].replace(0, pd.NA)
).round(4)
categoryFrame = categoryFrame.sort_values(by="GrossProfit", ascending=False)
return categoryFrame
def buildDailyTrend(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
dailyFrame = (
dataFrame.groupby("OrderDay")
.agg(
NetSales=("SalesAmount", "sum"),
GrossProfit=("GrossProfit", "sum"),
OrderCount=("OrderId", "nunique")
)
.reset_index()
.sort_values(by="OrderDay", ascending=True)
)
return dailyFrame
def buildMemberAnalysis(self, dataFrame: pd.DataFrame) -> pd.DataFrame:
memberFrame = (
dataFrame[dataFrame["MemberId"] != "Guest"]
.groupby("MemberId")
.agg(
OrderCount=("OrderId", "nunique"),
NetSales=("SalesAmount", "sum"),
GrossProfit=("GrossProfit", "sum")
)
.reset_index()
)
memberFrame["IsRepeatMember"] = memberFrame["OrderCount"].apply(
lambda value: "是" if value >= 2 else "否"
)
memberFrame = memberFrame.sort_values(by="NetSales", ascending=False)
return memberFrame
def beautifyWorkbook(self, outputFilePath: str) -> None:
workbook = load_workbook(outputFilePath)
headerFill = PatternFill("solid", fgColor="1F4E78")
headerFont = Font(color="FFFFFF", bold=True)
centerAlignment = Alignment(horizontal="center", vertical="center")
for sheetName in workbook.sheetnames:
sheet = workbook[sheetName]
sheet.freeze_panes = "A2"
for cell in sheet[1]:
cell.fill = headerFill
cell.font = headerFont
cell.alignment = centerAlignment
for columnCells in sheet.columns:
maxLength = 0
columnLetter = columnCells[0].column_letter
for cell in columnCells:
cellValue = "" if cell.value is None else str(cell.value)
if len(cellValue) > maxLength:
maxLength = len(cellValue)
sheet.column_dimensions[columnLetter].width = maxLength + 4
workbook.save(outputFilePath)
def exportReport(self, outputFilePath: str) -> None:
rawFrame = self.loadData()
cleanFrame = self.cleanData(rawFrame)
summaryFrame = self.buildSummary(cleanFrame)
storeFrame = self.buildStoreAnalysis(cleanFrame)
categoryFrame = self.buildCategoryAnalysis(cleanFrame)
dailyFrame = self.buildDailyTrend(cleanFrame)
memberFrame = self.buildMemberAnalysis(cleanFrame)
with pd.ExcelWriter(outputFilePath, engine="openpyxl") as writer:
cleanFrame.to_excel(writer, sheet_name="CleanData", index=False)
summaryFrame.to_excel(writer, sheet_name="Summary", index=False)
storeFrame.to_excel(writer, sheet_name="StoreAnalysis", index=False)
categoryFrame.to_excel(writer, sheet_name="CategoryAnalysis", index=False)
dailyFrame.to_excel(writer, sheet_name="DailyTrend", index=False)
memberFrame.to_excel(writer, sheet_name="MemberAnalysis", index=False)
self.beautifyWorkbook(outputFilePath)
def main() -> None:
basePath = Path.cwd()
sourceFilePath = basePath / "sampleSalesData.xlsx"
reportFilePath = basePath / "retailAnalysisReport.xlsx"
createSampleSalesFile(str(sourceFilePath), rowCount=1200)
analysisEngine = RetailAnalysisEngine(str(sourceFilePath))
analysisEngine.exportReport(str(reportFilePath))
print(f"示例数据已生成:{sourceFilePath}")
print(f"分析报告已输出:{reportFilePath}")
if name == “main”:
main()
运行
运行说明
安装依赖:
bash
pip install pandas openpyxl
将代码保存为 retailAnalysis.py
在 VS Code 终端运行:
bash
python retailAnalysis.py
运行完成后,会生成两个文件:
sampleSalesData.xlsx
retailAnalysisReport.xlsx
这个案例体现了哪些分析原理
这段代码虽然不复杂,但已经包含了很多企业数据分析的基本原理。
第一,先清洗,再计算。
很多新手一拿到数据就直接汇总,结果日期没转好、数值是文本、空值没处理,最后得出的报表自然不可靠。分析的第一步永远是保证数据质量。
第二,指标必须可定义。
什么是销售额,什么是毛利,退货怎么处理,复购率怎么算,这些都不是代码问题,而是指标口径问题。口径不统一,分析结果就不具备可比性。
第三,汇总要服务决策。
不是所有汇总都值得做。门店分析是为了找经营差异,品类分析是为了看结构贡献,日趋势是为了看波动,会员分析是为了看留存。每个结果页都应该对应一个业务问题。
第四,输出要便于业务使用。
很多人写脚本只输出一个CSV文件,技术上没问题,但业务同事未必爱看。导出Excel并做基础格式处理,本质上是提高分析结果的可用性。
业务解读示例
假设报表跑出来后,发现以下现象:
国贸店净销售额高,但毛利率偏低
轻食品类销量不错,但毛利额贡献一般
周边商品销量不大,但毛利率高
某一周退货明显上升
会员复购率只有 32%
这时就可以形成更接近经营动作的判断:
高销售低毛利,可能说明门店做了较多低毛利促销
轻食适合作为引流商品,但不能承担利润核心角色
周边商品适合做组合销售,提高客单价和毛利
退货异常需要回看门店执行、商品质量或活动规则
会员复购率偏低,说明需要优化会员触达和二次购买链路
这就是数据分析真正的价值:不是展示数字,而是帮助业务做判断。
2.2.4 pandas、xlwings与OpenPyXL联动的实际价值
很多初学者在学习Python处理Excel时,容易陷入一个误区:以为只要学会一个库就够了。实际上,企业里常用的几个库并不是竞争关系,而是分工关系。
一、pandas:负责数据处理主流程
pandas最强的地方,在于表格型数据的读取、清洗、转换、分组、汇总和分析。它很像“能编程的超级透视表”,尤其适合处理结构化数据。
常见操作包括:
读取 Excel、CSV
过滤数据
填充空值
删除重复值
转换日期和数值格式
分组聚合
拼接和合并数据表
透视统计
绝大多数经营分析脚本,核心处理都离不开 pandas。
二、OpenPyXL:负责Excel文件层面的格式控制
pandas可以导出Excel,但如果你还想做这些事:
设置标题背景色
调整列宽
冻结首行
设置字体样式
合并单元格
设置条件格式
那么就需要 OpenPyXL。它更像是Python与Excel文件格式之间的桥梁,擅长“修饰工作簿”。
前面的自动化报表案例里,beautifyWorkbook() 方法就是一个典型的 OpenPyXL 用法。
三、xlwings:负责与本地Excel软件交互
xlwings和前两个库最大的不同,是它不只是操作文件,还可以操作正在运行的 Excel 应用程序。它适合以下场景:
把DataFrame直接写入打开的Excel工作簿
调用本地Excel对象
与业务同事已有的模板文件打通
结合 VBA 或现成模板进行自动填报
实现“Python计算,Excel展示”的混合工作流
如果企业里已经沉淀了大量复杂Excel模板,而你又不想全部推倒重来,那么 xlwings 非常有价值。
三个库怎么分工最合适
工具库 核心作用 适合做什么
pandas 数据计算与处理 清洗、汇总、分析、建模前准备
OpenPyXL Excel文件样式与结构控制 美化报表、设置格式、固定模板输出
xlwings 与本地Excel应用联动 模板驱动填报、交互式办公自动化
可以把它理解成一条流水线:
pandas负责“算”
OpenPyXL负责“排”
xlwings负责“连”
这三者组合起来,正好对应企业分析工作的三个真实需求:
算得出来、排得好看、接得上现有流程。
xlwings 可选示例:把门店分析结果写入本地Excel
下面是一段可选代码,演示如何把分析结果写入本地Excel。需要说明的是,这段代码依赖本机已安装 Microsoft Excel,适合 Windows 或 macOS 办公环境。
python
from future import annotations
from pathlib import Path
import pandas as pd
import xlwings as xw
def exportStoreSheetWithXlwings(reportPath: str) -> None:
reportFile = Path(reportPath)
storeFrame = pd.read_excel(reportFile, sheet_name="StoreAnalysis")
app = xw.App(visible=False, add_book=False)
try:
book = app.books.add()
sheet = book.sheets[0]
sheet.name = "StoreAnalysis"
sheet.range("A1").value = storeFrame.columns.tolist()
sheet.range("A2").options(index=False, header=False).value = storeFrame
sheet.autofit()
outputPath = reportFile.parent / "storeAnalysisByXlwings.xlsx"
book.save(outputPath)
print(f"xlwings 输出完成:{outputPath}")
finally:
app.quit()
运行
安装命令如下:
bash
pip install xlwings
如果企业场景里需要“保留现有Excel模板”,那么 xlwings 的价值就会非常突出。比如财务部有固定周报模板,销售部有固定区域报表模板,人力部门有月度统计模板,这些都可以由 Python 自动把数据写进去,而不是人工复制粘贴。
2.2.5 认识DataFrame与Series这两个核心对象
很多人学 pandas 时,最开始觉得函数很多、语法很杂,实际上真正需要先吃透的概念只有两个:Series 和 DataFrame。
一、Series是什么
Series可以理解成“一列带标签的数据”。
比如一列销售额、一列订单日期、一列商品名称,本质上都可以是 Series。
它有两个关键组成部分:
值
索引
举个简单例子,如果你把“朝阳店、国贸店、望京店”三个门店的销售额放在一列里,这一列就是一个 Series。
二、DataFrame是什么
DataFrame可以理解成“由多个Series组成的一张表”。
它有行索引和列索引,最像我们平时在Excel中看到的二维表。
比如一张订单表,包含订单号、日期、门店、商品、数量、单价,这整张表就是一个 DataFrame。
三、为什么这两个概念重要
因为你在 pandas 里做的绝大多数操作,本质上都是以下几类变换:
从 DataFrame 取出一列,得到 Series
对 Series 做运算
把多个 Series 组合成新的 DataFrame
对 DataFrame 做筛选、分组、聚合、排序
理解了这一点,很多代码就不再神秘。
四、简短示例:DataFrame 与 Series 基本操作
python
from future import annotations
import pandas as pd
def buildSimpleSalesFrame() -> pd.DataFrame:
salesFrame = pd.DataFrame(
{
"StoreName": ["朝阳店", "国贸店", "望京店", "朝阳店"],
"SalesAmount": [1200, 1800, 1500, 900],
"OrderCount": [45, 60, 52, 33]
}
)
return salesFrame
def main() -> None:
salesFrame = buildSimpleSalesFrame()
salesSeries = salesFrame["SalesAmount"]
salesFrame["AvgTicket"] = salesFrame["SalesAmount"] / salesFrame["OrderCount"]
storeSummaryFrame = (
salesFrame.groupby("StoreName")
.agg(
TotalSales=("SalesAmount", "sum"),
TotalOrders=("OrderCount", "sum")
)
.reset_index()
)
print("原始数据:")
print(salesFrame)
print("\n销售额这一列Series:")
print(salesSeries)
print("\n按门店汇总后的DataFrame:")
print(storeSummaryFrame)
if name == “main”:
main()
运行
这个例子虽然简单,但把最核心的关系讲清楚了:
salesFrame[“SalesAmount”] 取出的是一个 Series
给 salesFrame[“AvgTicket”] 赋值,是在 DataFrame 里增加一列
groupby().agg() 是把明细表转换成汇总表
如果把 Excel 和 pandas 对照起来理解,会更容易上手:
Excel中的概念 pandas中的对应对象
一列数据 Series
一张工作表 DataFrame
筛选 条件过滤
透视表 groupby / pivot_table
公式列 新增计算列
五、分析角度上的理解
从业务上看,DataFrame 代表的是“事实表”,Series 代表的是“指标或字段”。
比如一张订单明细表就是事实表,里面的销售额、数量、成本、门店、客户编号等字段,就是构成分析视角的维度和指标。
所以,学 pandas 不是学一堆函数,而是在学习如何用程序表达“从明细到汇总、从数据到结论”的过程。
2.2.6 Python及常用扩展库的安装部署
要让代码在 VS Code 中稳定运行,环境准备不能草率。很多初学者觉得安装这件事不重要,真正写代码时报错才发现问题多半出在环境上,而不是逻辑上。
一、建议的基础环境
Python 版本:建议使用 Python 3.11 或 3.12
编辑器:VS Code 1.103.2
包管理:pip
虚拟环境:venv
二、为什么建议使用虚拟环境
虚拟环境的作用,是让每个项目有自己独立的依赖,不会互相污染。
比如一个项目用 pandas 2.2,另一个项目用旧版本,如果都装在全局环境里,就容易产生冲突。
三、推荐安装步骤
先在系统中安装 Python,并确认命令可用:
bash
python --version
pip --version
接着创建项目目录:
bash
mkdir DataAnalysisProject
cd DataAnalysisProject
创建虚拟环境:
bash
python -m venv .venv
激活虚拟环境:
Windows:
bash
.venv\Scripts\activate
macOS 或 Linux:
bash
source .venv/bin/activate
安装常用库:
bash
pip install pandas openpyxl xlwings matplotlib seaborn numpy
如果需要把依赖记录下来,可以执行:
bash
pip freeze > requirements.txt
以后换电脑或交给同事,只需要执行:
bash
pip install -r requirements.txt
四、VS Code 中的关键设置
打开项目目录后,建议完成以下操作:
安装 Python 扩展
选择正确的解释器,也就是刚创建的 .venv
打开终端,确认当前虚拟环境已启用
运行测试脚本,确认库安装成功
你可以新建一个 testEnv.py 文件,写入下面代码检查环境:
python
import pandas as pd
import openpyxl
print(“环境安装成功”)
print(pd.version)
print(openpyxl.version)
运行
五、安装时常见问题
问题1:python 命令找不到
通常是 Python 没有加入系统环境变量,或者安装时未勾选相关选项。
问题2:pip install 很慢
有时是网络问题,可以更换镜像源,但在正式项目中最好记录清楚依赖版本,避免环境不一致。
问题3:VS Code 运行时报错,但终端能运行
通常是 VS Code 没有选择对的 Python 解释器。
问题4:xlwings 安装成功但运行报错
多半是本机没有安装 Excel,或者Excel版本与系统环境存在兼容问题。
六、环境本身也是项目资产
很多人做分析只保存了代码,没有保存环境说明,导致自己过一段时间重新运行都困难。真正规范的项目,应至少包含:
源代码
示例数据或字段说明
依赖文件
运行说明
输出示例
这样项目才具备可复用价值。
2.2.7 认识Python IDLE与VS Code工作环境
虽然现代开发和分析更多使用 VS Code、PyCharm 这样的编辑器,但 IDLE 仍然有它的价值,尤其是在初学阶段。
一、IDLE 的特点
IDLE 是 Python 自带的轻量编程环境。它的优点是:
安装 Python 后通常即可使用
界面简单,适合测试小段代码
适合学习基本语法、函数、循环、条件判断
启动快,依赖少
如果你只是想验证某段语句是否正确,或者做最初的语言练习,IDLE 很方便。
二、VS Code 更适合正式分析项目
一旦进入真实业务项目,VS Code 的优势会明显得多:
支持项目级目录管理
支持虚拟环境切换
支持调试、断点、变量查看
支持Git版本控制
支持插件扩展
支持终端操作和批量文件处理
对于数据分析来说,VS Code 的价值不仅在“写代码”,更在于它能够承载完整项目流程。
三、两者如何分工
可以这样理解:
IDLE适合“学语法、做小实验”
VS Code适合“做项目、跑脚本、交付结果”
如果是初学者,先在 IDLE 中验证基础语法,再转到 VS Code 做完整项目,是比较平滑的路径。
四、实际工作中的建议
如果你面向商业分析开发,建议尽快以 VS Code 为主。原因很简单:
企业里的数据分析任务往往不是写几行代码就结束,而是需要保存脚本、维护版本、处理多个文件、输出报表、记录依赖。只有项目化工作方式,才能支撑长期使用。
2.3 ChatGPT协助分析的基本方法
2.3.1 先把问题变成可分析的任务
很多人使用ChatGPT效果不好,并不是工具问题,而是输入的问题本身就不清楚。
比如一句“帮我分析一下销量下降原因”,这类说法太模糊,里面至少有五个不明确点:
什么时间段下降
下降的是销量、销售额还是利润
分析对象是单店、区域还是全公司
有哪些可用字段
输出希望得到代码、思路、报表还是结论
所以,在借助ChatGPT之前,要先把模糊问题改写成可分析任务。
以“销量下降”为例,一个更合格的任务定义应该至少包括:
业务背景:连锁咖啡门店近三个月利润下降
分析目标:找到利润下降主因
数据范围:订单表、商品表、门店表、活动表
核心字段:日期、门店、品类、销售额、成本、活动标签、退货标记
输出形式:分析思路、Python代码、结论模板
约束要求:变量名驼峰式命名,兼容 Python 3.11
这种改写,本质上就是把自然语言问题转成半结构化需求。
谁能把需求说清楚,谁就更容易得到可用结果。
从管理学视角看,这其实也是需求分析能力。数据分析做得好的人,往往不只是会算,而是会提问、会定义、会限定边界。
2.3.2 ChatGPT是什么,它在分析工作中能做什么
在数据分析工作里,ChatGPT更像一个“高响应速度的分析助理”。它不能替代业务判断,但可以显著缩短从问题到初稿的时间。
它常见的作用有以下几类。
一、帮助梳理分析思路
当你面对一个复杂问题,比如“为什么某地区复购率下降”,一时没有完整思路时,可以让它先帮你拆问题:
先看客户数量是否减少
再看新老客户结构变化
再看订单频次是否下降
再看促销活动是否中断
再看不同品类购买链路是否变化
这种拆解非常有价值,因为很多分析的难点不是不会算,而是不知道该从哪里开始。
二、帮助生成代码初稿
比如你已经明确要用 pandas 做门店维度汇总,但不想从头敲代码,那么可以让它先生成一个初版,再由你根据实际字段调整。
三、帮助解释代码和结果
有时候别人写了一段代码,你接手时看不懂,这时可以让它逐段解释。
同理,报表跑出来后,也可以让它把技术结果改写成适合业务汇报的话术。
四、帮助优化表达
分析报告常见问题不是内容不够,而是写得太技术化。
比如“字段经groupby后做聚合计算得出同比下降”,业务同事未必爱看。改成“同店客流下降叠加高毛利商品占比下滑,是本月利润走弱的主要原因”,表达就更适合管理场景。
五、帮助做提示词模板沉淀
高频任务如果每次都重新描述,会很浪费时间。
把常见分析任务整理成模板,比如销售分析模板、库存分析模板、会员分析模板,后续直接替换字段和场景即可。
不过也要注意,ChatGPT在分析工作中的最佳定位是:
帮你提速
帮你拆解
帮你起草
帮你润色
但真正负责口径确认、数据真实性和业务判断的,仍然是分析人员本人。
2.3.3 想获得更合适的答案,先学会写清提示
提示词写得好不好,直接决定结果能不能落地。
一个高质量提示词,通常至少包括六个元素:
角色或背景
任务目标
数据结构
输出要求
约束条件
风格要求
例如,同样是让它生成代码,下面两种写法效果差别会很大。
模糊写法
帮我写个销售分析代码。
这种提示的问题是:
没有业务背景、没有字段信息、没有输出目标、没有代码规范,得到的往往只能是通用示例。
清晰写法
请基于零售门店订单数据编写一段Python代码,使用 pandas 完成数据清洗和经营分析。
字段包括:OrderId、OrderDate、StoreName、ProductCategory、ProductName、Quantity、UnitPrice、CostPrice、MemberId、ReturnedFlag。
请输出:
总销售额、毛利额、毛利率、订单数、平均订单金额
按门店汇总的销售与毛利分析
按品类汇总的利润贡献分析
每日销售趋势表
代码要求兼容 Python 3.11,可在 VS Code 中运行,函数名和变量名采用驼峰命名法,代码结构清晰,并加入必要注释。
后者的优点就在于,它把“想要什么”说清楚了。
对方不需要猜,输出自然更贴合需求。
提示词设计的实用原则
不要只说主题,要说任务
不要只说任务,要说数据
不要只说数据,要说输出
不要只说输出,要说约束
不要只说约束,要说使用场景
一句话概括就是:
把提示词写成需求说明书,而不是一句口头指令。
2.3.4 借助ChatGPT生成、检查与改写代码
很多人把“生成代码”当作ChatGPT最主要的用途,其实更有价值的,是“生成初稿后继续检查和改写”。
因为在真实项目中,第一版代码通常都不是最终版本。真正有效的工作方式是四步:
先生成可运行初稿
用样例数据验证
根据报错和字段差异修正
再做性能、结构和表达优化
也就是说,正确姿势不是“一次性生成完美代码”,而是“通过多轮迭代加快开发”。
下面给出一个客户价值分析的小型商业案例,说明如何把分析代码从“会跑”推进到“有业务意义”。
商业案例:会员RFM价值分层
RFM 是客户运营中最常见的一种分层方法:
R:Recency,最近一次购买距离今天多久
F:Frequency,购买频次高不高
M:Monetary,消费金额高不高
企业通过 RFM 可以把会员分成高价值客户、沉睡客户、潜力客户等,从而匹配不同运营策略。
下面是一段可直接运行的RFM示例代码,使用前面生成的 sampleSalesData.xlsx 即可。
python
from future import annotations
from pathlib import Path
import pandas as pd
class CustomerRfmAnalyzer:
def __init__(self, sourceFilePath: str) -> None:
self.sourceFilePath = Path(sourceFilePath)
def loadAndCleanData(self) -> pd.DataFrame:
dataFrame = pd.read_excel(self.sourceFilePath)
dataFrame["OrderDate"] = pd.to_datetime(dataFrame["OrderDate"], errors="coerce")
dataFrame["Quantity"] = pd.to_numeric(dataFrame["Quantity"], errors="coerce").fillna(0)
dataFrame["UnitPrice"] = pd.to_numeric(dataFrame["UnitPrice"], errors="coerce")
dataFrame["ReturnedFlag"] = pd.to_numeric(dataFrame["ReturnedFlag"], errors="coerce").fillna(0).astype(int)
dataFrame["MemberId"] = dataFrame["MemberId"].fillna("Guest")
dataFrame = dataFrame.dropna(subset=["OrderDate", "UnitPrice"])
dataFrame = dataFrame[dataFrame["MemberId"] != "Guest"].copy()
dataFrame["SalesAmount"] = dataFrame["Quantity"] * dataFrame["UnitPrice"]
dataFrame.loc[dataFrame["ReturnedFlag"] == 1, "SalesAmount"] = (
dataFrame.loc[dataFrame["ReturnedFlag"] == 1, "SalesAmount"] * -1
)
return dataFrame
def scoreByQuantile(self, series: pd.Series, reverseScore: bool = False) -> pd.Series:
rankSeries = series.rank(method="first")
if reverseScore:
scoreSeries = pd.qcut(rankSeries, 5, labels=[5, 4, 3, 2, 1])
else:
scoreSeries = pd.qcut(rankSeries, 5, labels=[1, 2, 3, 4, 5])
return scoreSeries.astype(int)
def buildRfmResult(self) -> pd.DataFrame:
dataFrame = self.loadAndCleanData()
snapshotDate = dataFrame["OrderDate"].max() + pd.Timedelta(days=1)
rfmFrame = (
dataFrame.groupby("MemberId")
.agg(
LastOrderDate=("OrderDate", "max"),
Frequency=("OrderId", "nunique"),
Monetary=("SalesAmount", "sum")
)
.reset_index()
)
rfmFrame["RecencyDays"] = (snapshotDate - rfmFrame["LastOrderDate"]).dt.days
rfmFrame["RScore"] = self.scoreByQuantile(rfmFrame["RecencyDays"], reverseScore=True)
rfmFrame["FScore"] = self.scoreByQuantile(rfmFrame["Frequency"])
rfmFrame["MScore"] = self.scoreByQuantile(rfmFrame["Monetary"])
rfmFrame["TotalScore"] = rfmFrame["RScore"] + rfmFrame["FScore"] + rfmFrame["MScore"]
def mapSegment(totalScore: int) -> str:
if totalScore >= 13:
return "高价值客户"
if totalScore >= 10:
return "潜力成长客户"
if totalScore >= 7:
return "普通维护客户"
return "沉睡预警客户"
rfmFrame["CustomerSegment"] = rfmFrame["TotalScore"].apply(mapSegment)
rfmFrame = rfmFrame.sort_values(by="TotalScore", ascending=False)
return rfmFrame
def main() -> None:
sourceFilePath = Path.cwd() / "sampleSalesData.xlsx"
analyzer = CustomerRfmAnalyzer(str(sourceFilePath))
resultFrame = analyzer.buildRfmResult()
outputPath = Path.cwd() / "customerRfmReport.xlsx"
resultFrame.to_excel(outputPath, index=False)
print(resultFrame.head(10))
print(f"RFM分析结果已输出:{outputPath}")
if name == “main”:
main()
运行
这段代码背后的业务意义
RFM之所以常用,不是因为公式复杂,而是因为它把客户价值拆成了三个最核心维度:
最近有没有买
买得频不频繁
买得多不多
对经营来说,这三件事对应的动作很明确:
高价值客户:重点维护,提供会员权益和新品优先体验
潜力成长客户:加强转化,推动第二次、第三次购买
普通维护客户:维持日常触达,避免流失
沉睡预警客户:做召回活动,分析流失原因
这说明一件事:代码只是工具,真正关键的是指标和业务策略之间是否形成闭环。
生成代码时要特别注意什么
使用ChatGPT辅助代码开发时,至少要注意以下几点:
不要直接拿陌生代码上线,要先用样例数据测试
要核对字段名是否和实际数据一致
要检查异常处理是否充分
要检查时间、金额、空值、重复值的处理是否合理
要补上日志、注释和输出说明
换句话说,ChatGPT最擅长的是把“从零到一”加速,但把“一变成可交付成果”,仍然需要人为把关。
2.3.5 面向业务重述问题与搭建提示模板
数据分析做不好,往往不是因为算不出来,而是因为问题问偏了。
企业里的很多问题看似在问“结果”,其实真正应该问的是“结构、过程和原因”。
下面看几个典型例子。
例子一:原问题不够好
为什么最近销售变差了?
这个问题的问题在于:
时间不明确
范围不明确
指标不明确
比较对象不明确
更合理的改写可以是:
请分析 2025 年第一季度与 2024 年第四季度相比,华北区域门店销售额和毛利额下降的主要原因。请分别从门店、品类、会员、促销活动和退货情况五个维度展开,并给出需要优先核查的指标清单。
这样的提问更容易得到可执行的分析框架。
例子二:从“看数据”改成“做决策”
原问题:
帮我做一个库存分析。
改写后:
请基于商品库存表、销售表和采购表,设计一套库存分析思路,重点识别高库存低周转商品、潜在缺货商品和采购节奏异常商品,并给出适合周报展示的核心指标与Python实现思路。
这时,任务目标已经从“分析一下”变成了“识别问题并支持动作”。
通用提示模板
下面是一套适合数据分析场景的提示模板,可直接复用:
text
你现在扮演企业数据分析顾问。
业务背景:
[描述业务场景,例如零售、会员、电商、供应链]
分析目标:
[说明要解决的核心问题]
数据表与字段:
[列出表名、字段名、字段含义]
希望输出:
- 分析思路
- 关键指标定义
- Python代码
- 结果解读建议
- 可视化建议
约束条件:
- 使用 Python 3.11
- 代码可在 VS Code 中运行
- 函数名和变量名使用驼峰命名法
- 代码结构清晰
- 输出语言通俗易懂
这样的模板好处有两个:
每次只需要替换业务背景和字段
输出结果会更稳定、更接近实际需求
从长期看,提示模板本身也是一种分析资产。沉淀得越多,工作效率越高。
2.3.6 使用ChatGPT做数据分析的一套通用步骤
把ChatGPT真正融入分析工作,可以按下面这套流程来走。
第一步:先写业务问题,不要急着写代码
先问自己三件事:
业务到底要知道什么
分析结果给谁看
看完后要做什么动作
这一步做不好,后面所有代码都可能跑偏。
第二步:列出数据字段和口径
把关键字段整理清楚,尤其是:
主键是什么
时间字段是什么
金额字段口径是什么
退货、取消、作废如何处理
是否有空值和异常值
这一步决定分析是否可靠。
第三步:让ChatGPT先给分析框架
不要一上来就要代码,先要思路。
比如让它先列维度、指标、分析顺序、可能原因,这样更有利于你判断路线对不对。
第四步:再让它生成代码初稿
此时再进入代码阶段,效果会更稳。
因为你已经知道要算什么,而不是盲目索要脚本。
第五步:用样例数据做验证
验证至少要看三件事:
代码能不能运行
结果有没有明显异常
指标是否符合业务口径
第六步:让它帮你优化表达和报告
代码跑通后,还可以让它帮你把结果改写成:
管理层汇报版
业务部门复盘版
项目文档说明版
培训材料版
第七步:沉淀成模板
每完成一次典型任务,就把以下内容保存下来:
提示词模板
字段说明模板
代码模板
报告模板
常见问题清单
长期下来,你的分析能力就不再只是“会做一次”,而是“会复用很多次”。
2.4 提示词设计的实战技巧
2.4.1 提示词不是命令,而是需求说明书
很多人把提示词理解成一句命令,比如“帮我写代码”“帮我分析数据”。这种写法的问题是,它只给了动作,没有给上下文。
而在真实工作中,一个合格需求至少要说明:
谁在用
用来解决什么问题
数据长什么样
输出长什么样
有哪些规则不能违反
所以,写提示词时最好把自己当作项目需求提出者,而不是聊天提问者。
比如下面这个提示词就更像需求说明书:
我需要为连锁零售企业做一份经营分析脚本。
数据来自Excel订单表,字段包括门店、订单日期、商品品类、商品名称、数量、单价、成本、会员编号和退货标记。
请使用 pandas 编写可运行的Python代码,完成数据清洗、门店汇总、品类汇总、每日趋势分析,并导出到Excel。
代码要求兼容 Python 3.11,可在 VS Code 中运行,函数名和变量名使用驼峰命名法,输出结果便于业务同事阅读。
这类写法的本质,是把“我想要什么”完整交代出来。
2.4.2 通用写法上的基础技巧
高质量提示词通常有几个通用技巧。
一、写清目标,不写空话
“帮我分析一下”这种写法太宽泛。
应该改成“请识别利润下降原因”“请计算复购率并做客户分层”“请比较活动前后转化变化”。
二、限定对象和范围
比如:
时间范围:近30天、本季度、去年同期
分析对象:单店、区域、全渠道、某商品线
数据范围:订单表、会员表、库存表
范围越清楚,结果越实用。
三、说明输出形式
你到底要的是:
思路
代码
SQL
解释
汇报文案
图表建议
整体方案
输出形式不说清楚,很容易出现“你想要方案,它却给你代码”的情况。
四、提前写上约束条件
例如:
代码兼容 Python 3.11
使用 pandas
输出成表格
解释面向业务人员
变量名使用驼峰命名法
这些约束越明确,返工越少。
2.4.3 与数据场景相关的描述方法
数据分析类提示词和普通聊天最大的差别,在于它需要更强的数据上下文。
描述数据时,建议至少说明以下内容:
表名或数据来源
字段名
字段含义
数据粒度
时间范围
可能存在的数据问题
例如:
订单表粒度为订单明细行,一笔订单可能包含多个商品。
字段 OrderDate 为下单日期,ReturnedFlag 表示是否退货,退货订单仍保留在原表中。
SalesAmount 需要由数量乘以单价计算,若为退货则按负值处理。
数据时间范围为 2025 年 1 月到 2025 年 3 月。
这种描述非常关键,因为它直接关系到汇总逻辑。
例如,一笔订单多商品和一笔订单一行,在订单数计算上就完全不同;退货是否记负值,也会直接影响销售额和毛利口径。
数据提示里最容易漏掉的内容
粒度
去重规则
时间字段定义
状态字段含义
缺失值处理规则
而这些恰恰是最影响结果准确性的内容。
2.4.4 与表达风格相关的控制技巧
同样一份分析结果,面向不同对象,表达方式应该不同。
面向管理层
要点是简洁、结论先行、突出动作。
比如:
利润下滑的三大原因
建议优先处理的两项动作
风险点和机会点
面向业务同事
要点是可执行、接地气、能落地。
比如:
哪些门店需要重点复盘
哪些商品适合调整陈列
哪类会员需要重点召回
面向技术团队
要点是逻辑清晰、字段明确、流程可复现。
比如:
数据来源
清洗规则
指标定义
代码结构
运行步骤
因此,在提示词中加入表达风格要求非常必要。
例如:
请用经营汇报口吻总结
请用通俗语言解释,不要堆术语
请适合给管理层做周会汇报
请用技术文档风格输出步骤和代码
这样能显著提高结果可用性。
2.4.5 与输出形式相关的约束方式
很多时候,结果“不好用”不是因为内容不对,而是因为格式不对。
所以,输出形式一定要提前约束。
常见约束方式包括:
请分点输出
请先给思路,再给代码
请以Markdown表格展示指标定义
请输出完整可运行代码
请附上运行说明
请增加示例数据
请加入异常处理
请给出图表推荐方案
下面是一个更完整的输出约束示例:
请按以下顺序输出:
业务理解
分析思路
指标说明
Python代码
结果解读示例
常见错误提醒
这种格式特别适合实际项目,因为它覆盖了从“理解”到“交付”的完整过程。
2.4.6 提升效率的拆分与迭代方法
复杂任务不要一次性提完,最好拆分。
这是提高成功率和节省返工时间的关键。
一、按阶段拆
例如一个完整经营分析任务,可以拆成:
先做问题定义
再做指标设计
再做字段映射
再做代码生成
再做结果解读
最后做汇报改写
二、按模块拆
例如:
先做门店分析
再做品类分析
再做会员分析
最后汇总成报告
三、按角色拆
例如同一份结果,可以分别生成:
技术版说明
业务版说明
管理层汇报版说明
拆分的好处在于,每次聚焦一个目标,更容易把细节做对。
尤其当字段多、逻辑复杂时,分步推进比一次性输出更可靠。
四、把错误也当作输入的一部分
如果代码运行报错,不要只说“报错了”,而要把以下内容一并提供:
报错完整信息
相关代码片段
当前字段名
预期结果
这样下一轮修正会更快。
2.4.7 中英文混合环境下的语言处理建议
数据分析工作里经常会遇到中英文混合环境:
字段名是英文
报告要写中文
库函数是英文
业务术语可能是中英混排
这时最重要的是统一规范,避免一会儿一个说法。
建议一:字段名保持稳定
代码中的字段名最好和原始数据一致,避免中途随意改来改去。
如果原始字段名是英文,可以在报告里再用中文解释。
建议二:业务术语保持一致
例如:
GrossMargin 固定解释为“毛利率”
RepeatRate 固定解释为“复购率”
InventoryTurnover 固定解释为“库存周转率”
不要同一份文档里一会儿写“回购率”,一会儿写“复购率”,否则会影响理解。
建议三:提示词中可以明确要求语言风格
例如:
代码变量用英文驼峰命名
结果解释用中文
指标表头输出中英文对照
图表标题用中文
建议四:跨团队协作时保留字段字典
字段字典至少包括:
字段名
中文含义
数据类型
是否主键
口径说明
示例值
这会极大提高沟通效率,也能减少误解。
2.5 本章的学习路径与实践建议
2.5.1 先学什么,再练什么
很多人学数据分析时容易焦虑,感觉要学的东西很多:Excel函数、pandas、SQL、可视化、机器学习、提示词设计、自动化报表,结果学得越多越乱。更有效的方式,是按工作链路来学。
推荐的顺序如下:
第一阶段:先建立分析意识
先搞清楚以下问题:
什么是业务问题
什么是指标
什么是数据粒度
什么是口径统一
什么是清洗、汇总、解释和输出
没有这些基础,工具学再多也会散。
第二阶段:先把Excel用熟
至少掌握:
常用函数
数据透视表
条件格式
图表
文本分列
去重
筛选与排序
这是很多分析工作的第一层基础。
第三阶段:再学Python做自动化
重点掌握:
基础语法
读写Excel与CSV
pandas数据处理
分组汇总
结果导出
异常处理
到这一步,已经可以解决大量日常经营分析任务。
第四阶段:让ChatGPT参与流程
重点练三个能力:
把问题说清楚
把字段描述清楚
把输出要求限定清楚
这一步会显著提高分析效率。
第五阶段:做项目化练习
建议至少做这几类练习:
销售经营分析
客户复购分析
商品品类分析
库存周转分析
活动效果分析
每做完一个项目,就沉淀一套模板。长期积累后,能力提升会非常快。
2.5.2 不同类型读者的学习路线
不同背景的人,学习重点应当不同。
一、业务管理者
重点不一定是亲自写代码,而是理解:
数据分析能解决什么问题
指标体系怎么搭
如何看懂分析结论
如何提出高质量分析需求
管理者如果能把问题提对,团队效率会提升很多。
二、Excel基础较强的运营人员
这类读者的优势是熟悉业务和表格,最适合向“Python自动化分析”进阶。
建议路径是:
保留Excel做结果查看
用Python替代重复整理工作
用ChatGPT辅助生成初版脚本
这样转型成本相对最低。
三、Python初学者
这类读者不要急着做复杂模型,应先掌握:
pandas读写
清洗规则
分组汇总
Excel输出
结果解释
先能把经营周报自动跑出来,再谈更复杂的预测和建模。
四、数据分析岗位从业者
建议把重点放在三件事上:
业务理解深度
代码复用能力
提示词工程化能力
真正拉开差距的,往往不是会不会写 groupby,而是能不能把业务问题转成稳定可复用的分析框架。
五、需要做商业交付的开发人员
如果需要面向企业做项目交付,建议重点加强:
项目结构组织
环境管理
模块化代码
字段字典和文档
错误处理
输出模板
商业项目最怕的不是写不出,而是交付后维护不了。
2.5.3 使用提示词和代码时常见问题及应对办法
在实际使用过程中,最常见的问题大致有以下几类。
问题一:提示词太笼统,结果不贴需求
表现:
输出太空泛
代码字段不对
解释不符合业务场景
解决办法:
明确业务背景
列出字段名和字段含义
说明输出形式和约束条件
问题二:代码能运行,但结果不可信
表现:
汇总结果与Excel核对不一致
订单数明显异常
金额正负号处理错误
解决办法:
检查数据粒度
检查去重规则
检查退货、取消、作废口径
先抽样验证,再全量运行
问题三:环境问题导致脚本跑不起来
表现:
模块找不到
解释器错误
Excel库版本不兼容
解决办法:
固定Python版本
使用虚拟环境
保存 requirements.txt
在项目文档中写清运行步骤
问题四:输出结果有数字,但没有结论
表现:
报表很多,业务不知道看什么
图表不少,但没有行动建议
解决办法:
每个结果页只服务一个问题
结论要回答“为什么”和“怎么办”
报告中加入重点发现和建议动作
问题五:ChatGPT生成内容看起来正确,但细节有误
表现:
字段名编造
指标口径默认错误
边界条件未考虑
解决办法:
不要直接照搬
用样例数据校验
逐条核对字段与业务规则
把错误信息作为下一轮输入继续修正
问题六:分析做完后无法沉淀复用
表现:
下次还要从头做
同类任务重复劳动
不同人做法差异大
解决办法:
保存代码模板
保存提示词模板
建立字段字典
建立结果解释模板
建立常见问题清单
问题七:技术结果和业务语言脱节
表现:
技术同事看得懂,业务同事看不懂
结论过于术语化
解决办法:
输出两套版本:技术版和业务版
多用经营语言解释指标变化
少堆函数名和处理细节,多讲业务意义
从长期工作经验看,数据分析最重要的不是某一个函数,也不是某一种工具,而是三件事:
能把问题定义清楚
能把数据处理稳定
能把结果说成人能用的话
只要这三件事建立起来,Excel、Python和ChatGPT都能成为真正有生产力的工具,而不是堆在简历上的名词。
本章小结
本章的重点,不是单独讲某个工具怎么用,而是讲清楚三者如何形成一套完整的数据分析方法。
可以把核心结论归纳为以下几点:
数据分析的起点不是代码,而是业务问题。
Excel适合快速查看、核对和汇报,Python适合批量处理和自动化,ChatGPT适合问题拆解、代码辅助和表达优化。
pandas、OpenPyXL、xlwings分别对应“算、排、连”三种能力,组合使用更贴近企业实务。
DataFrame 和 Series 是理解 pandas 的关键起点。
提示词不是一句命令,而是一份需求说明书。
高质量分析必须把概念、指标、代码和业务动作连成闭环。
真正有价值的不是做出一次报表,而是形成可复用、可交付、可迭代的分析流程。
如果把本章的内容真正吃透,后续无论做销售分析、会员分析、库存分析还是经营复盘,都会更容易上手。因为你已经掌握的,不再只是某一个工具,而是一整套从问题定义到业务落地的分析框架。
更多推荐



所有评论(0)