🧪 场景设定(能换数据就能复用)
数据集:Kaggle 经典 “superstore.csv” (超市 2015-2018 订单)
目标:
- 找出“到底谁在拖利润后腿?”
- “哪个品类/地区最香?”
- “打折真的有用吗?”
1️⃣ 环境一键安装(小白照抄)
# 新建环境(可选)
conda create -n ana python=3.11
conda activate ana
# 核心三件套
pip install pandas seaborn matplotlib jupyter plotly -i https://pypi.tuna.tsinghua.edu.cn/simple
2️⃣ 导入 & 初窥门径
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.express as px
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_csv('superstore.csv')
print(df.shape) # (9994, 21)
df.head()
表情包:
“头秃第一步,形状先看清”🦲
3️⃣ 数据清洗 = 做饭前洗菜🥬
# 缺失值
print(df.isna().sum()) # 无缺失,爽!
# 重复行
df = df.drop_duplicates()
# 日期转 datetime,方便时间序列
df['Order Date'] = pd.to_datetime(df['Order Date'])
# 新增两列辅助
df['Year'] = df['Order Date'].dt.year
df['Profit Margin'] = df['Profit'] / df['Sales']
4️⃣ 核心指标 = 老板最爱看的数💰
summary = {
'总销售额': df['Sales'].sum(),
'总利润': df['Profit'].sum(),
'整体利润率': df['Profit'].sum() / df['Sales'].sum(),
'订单量': len(df),
'客单价': df['Sales'].sum() / len(df)
}
summary
输出示例:
{'总销售额': 2.3M, '总利润': 0.31M, '整体利润率': 13.3%, ...}
5️⃣ 可视化 1:利润 = 世界地图🗺️
geo_profit = df.groupby('State')['Profit'].sum().reset_index()
fig = px.choropleth(geo_profit,
locations='State',
locationmode='USA-states',
color='Profit',
scope='usa',
title='各州利润热力图')
fig.show()
一眼看出“加州红到发紫,德州蓝到亏损”😅
6️⃣ 可视化 2:品类利润对比 → 条形图📊
cat_profit = df.groupby('Category')['Profit'].sum().sort_values()
sns.barplot(x=cat_profit.values, y=cat_profit.index, palette='vlag')
plt.title('品类利润排行榜')
plt.xlabel('利润 ($)')
结论:
Table > Chair > Storage > Supplies( Supplies 是利润黑洞!)
7️⃣ 可视化 3:折扣 vs 利润率 → 散点 + 回归线📈
sns.regplot(x='Discount', y='Profit Margin', data=df, scatter_kws={'alpha':0.3})
plt.title('折扣 & 利润率关系')
plt.xlabel('折扣率')
plt.ylabel('利润率')
洞察:
折扣>0.2 时利润率几乎全负!“打折狂魔”真·打骨折🦴
8️⃣ 时间序列:看趋势📅
monthly = df.groupby(df['Order Date'].dt.to_period('M'))['Profit'].sum()
monthly.plot(figsize=(10,4), marker='o')
plt.title('月度利润趋势')
plt.ylabel('利润 ($)')
发现:
每年 11-12 月飙升(黑五+圣诞),Q1 回落 → 库存/营销节奏可提前。
9️⃣ 高级补充:RFM 客户分层(附代码)🎯
import datetime as dt
rfm = df.groupby('Customer ID').agg({
'Order Date': lambda x: (dt.datetime(2018,12,31) - x.max()).days, # Recency
'Order ID' : 'nunique', # Frequency
'Sales' : 'sum' # Monetary
})
rfm.columns = ['Recency','Frequency','Monetary']
# 打分 1-5
rfm['R'] = pd.qcut(rfm['Recency'], 5, labels=5-range(5))
rfm['F'] = pd.qcut(rfm['Frequency'].rank(method='first'), 5, labels=range(1,6))
rfm['M'] = pd.qcut(rfm['Monetary'], 5, labels=range(1,6))
rfm['RFM'] = rfm['R'].astype(str) + rfm['F'].astype(str) + rfm['M'].astype(str)
把 555 当“黄金 VIP”重点营销,把 111 当“沉睡用户”召回。
🔟 报告输出:Jupyter → HTML/PDF → 群发📧
# 一键转 HTML(含交互图)
jupyter nbconvert analyse.ipynb --to html --template classic
# 加 PDF 也行(需装 wkhtmltopdf)
jupyter nbconvert analyse.ipynb --to pdf
再配个 Markdown 单元写结论:
- 加州 & Table 品类最赚钱→加大库存
- 折扣≥20% 利润率为负→设硬门槛 15%
- 11-12 月占全年 35%→提前 2 个月备货/招人
🏁 总结口诀(背它!)
“pd 读数 → 洗缺失 → 分组聚合 → seaborn 画图 → plotly 交互 → RFM 分层 → nbconvert 发报告”
一套连招,10 行代码就能让老板看见钱💰