资讯动态

从doc顾客流量调查表到转化率分析的pandas数据清洗实战

发布时间:2026/9/18 23:01:28 来源:尧图企业网站定制
简介《顾客流量调查表.doc》是一份供零售店铺、商场或服务场所使用的顾客流量记录与简易分析模板面向经营者、店长及市场营销人员旨在解决营业数据零散、凭经验决策的问题。表格设置了时间、人数、商品、购买数量等关键字段以羊毛衫为例演示了记录方法用户可替换为任意商品长期跟踪。通过每日登记不同时段的客流量与成交量能够识别门店的高峰期与低谷期掌握畅销品与滞销品的动态进而优化排班计划、调整库存结构、安排促销节点并为营业时间延长或缩短提供参考依据。压缩包内仅有一个doc文档大小约15KB内容简洁、字段直观下载后稍加修改即可用于实际调查。目前已有68人学习浏览适合需要快速建立客流观测机制的中小商户、连锁门店及商业数据分析初学者使用。1. 顾客流量调查表不是一张表先把记录动作变成数据协议很多专柜和独立店拿到的营业报表只有销售额缺了最重要的分母进店人数。于是运营者会打印一张类似“顾客流量调查表.doc”的纸让店员在每个整点记录顾客数再在商品行后面写几笔成交。这份文档看起来只有“时间、人、商品、数”四段信息实际已经把零售数据分析的最小协议定义清楚了时间粒度、流量口径、商品维度、购买人数。它解决的是“系统报表回答不了”的问题——哪一小时客流最大、哪些顾客只逛不买、某类商品在哪个时段成交最集中。适合专柜、品牌门店和没有 BI 系统的小型零售体不需要额外硬件一张表加后续的数据处理就能跑通全部流程。2. doc 表格的字段还原与结构化从“人”到“数”的口径拆解2.1 先读懂原始表头时间、人、商品、数分别记录什么原始 doc 的表头排布是“时间、人、商品、数”示例数据写在羊毛衫这一行50 4 1 10 5 8 2 3 5 7 5。这里的“50”容易误读为客流实际在表格语境中它是商品行的总计或备注值后面从 8 点到 5 点的 10 个数字才是每个整点的购买顾客数。特别注意两点第一“数”记录的是购买该商品的顾客数不是商品件数一个人买两件也只记 1第二表头里的8 9 10 11 12 1 2 3 4 5 6是十二小时制写法下午的 1 到 6 必须映射为 13 到 18 点否则排序和分析会全乱。这一节的核心是约定口径。如表所示原表字段真实业务含义规范化字段数据类型时间一天内的营业整点12 小时制需转 24 小时制hourint人该小时进入门店/柜台的顾客总数trafficint商品被观察的商品品类本表示例为羊毛衫productstr数该小时内实际购买该商品的顾客数量buyersint表头备注调查日期与调查科组date / groupstr / int口径一旦定错后面所有转化率都失真。常见做法是先在表头旁补一列“时段说明”把 12 制转成 24 制。也可以直接修改原表把1到6改成13到18避免后期在代码里反复做映射。2.2 用 LibreOffice 把 .doc 转成 Excel避免手工重录.doc 是二进制老格式python-docx读不了直接改扩展名也会乱码。最稳的方式是用 LibreOffice 的命令行转换日常在 Windows 和 Linux 上都能用soffice --headless --convert-to xlsx --outdir ./flow_data 顾客流量调查表.doc命令里的--headless表示不启动界面--convert-to xlsx指定输出类型--outdir指定文件导出目录。转换完成后打开flow_data/顾客流量调查表.xlsx检查一通行列结构原 doc 如果有合并单元格转换后可能出现空行或错位这是预期现象。遇到这种情况不要硬改直接以转换后的 xlsx 为底稿把表头重写为标准字段。2.3 建一张长表日期、小时、客流、商品、购买人数分析用数据要用“长表”而不是原始“宽表”。宽表里每小时是一列不方便按商品、日期做聚合。我用 Python 把转换后的数据清洗成 CSV代码可以直接复制import csv from itertools import zip_longest hours [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] traffic [5, 7, 9, 12, 10, 8, 6, 4, 3, 3, 2] # 每小时进店人数 buyers [4, 1, 10, 5, 8, 2, 3, 5, 7, 5] # 原表羊毛衫购买数据18 点没填写 with open(flow_long.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([date, hour, traffic, product, buyers]) for h, t, b in zip_longest(hours, traffic, buyers, fillvalueNone): writer.writerow([2025-04-13, h, t, 羊毛衫, b])这里使用zip_longest而不是zip是为了让 18 点这一行保留下来buyers 字段写成空值。空值和 0 的语义完全不同空值表示店员漏记0 表示记录了但没人买。后续分析里必须把两者分开处理。utf-8-sig编码是为了让生成的 CSV 能被 Excel 直接双击打开而不出现中文乱码。3. 用 pandas 算客流量、购买人数与转化率先清洗再算指标3.1 读取长表并检查字段类型拿到 CSV 后直接用 pandas 加载先别急着算平均数第一件事是检查类型和缺失值import pandas as pd df pd.read_csv(flow_long.csv) df[date] pd.to_datetime(df[date]) df[traffic] pd.to_numeric(df[traffic], errorscoerce) df[buyers] pd.to_numeric(df[buyers], errorscoerce) print(df.dtypes) print(df.isna().sum())pd.to_numeric(..., errorscoerce)会把空字符串或非数字内容转成 NaN而不是让整列变成 object 类型。这一步很关键因为原 doc 里大量数字是手工填写的经常混入全角数字、星号或文字备注。如果某列出现object类型说明表里混进了非数字内容需要回到原始单元格排查。3.2 计算客流量、日均购买人数和转化率在单日数据里客流量就是 traffic 的求和购买人数是 buyers 的求和如果调查了多天就必须按日期分组再汇总daily df.groupby(df[date].dt.date).agg( traffic_sum(traffic, sum), buyers_sum(buyers, sum) ) daily[conversion] daily[buyers_sum] / daily[traffic_sum] * 100 print(daily)groupby(df[date].dt.date)是把 datetime 字段归一化到日期粒度避免同一天内的小时数据被拆开。agg里用traffic_sum和buyers_sum重命名结果列方便后续直接用列名访问。转化率用购买人数除以客流量而不是用销售额除以客流量因为这张表采集的是“顾客数”而不是“金额”。如果你想看每个小时的平均购买人数而不是整天总和可以这样hourly df.groupby(hour)[buyers].agg([sum, mean, count]) print(hourly)这里的count统计的是非空记录不是总和。当 18 点缺失时count会显示 10mean会用非空值计算这比直接mean()更透明。3.3 异常值处理重复时间段、负数和缺失值手工表格最常见的三类问题同一时间段被抄了两遍、数字写成负数、某个整点整行没填。用代码扫一遍duplicated df[df.duplicated(subset[date, hour, product], keepFalse)] negative df[(df[[traffic, buyers]] 0).any(axis1)] missing_buyers df[df[buyers].isna()] print(重复记录\n, duplicated) print(负数记录\n, negative) print(缺失购买记录\n, missing_buyers)duplicated的subset参数指定判断重复的键keepFalse让所有重复行都显示而不仅仅是后面的行。负数用0判断后接.any(axis1)只要某行的 traffic 或 buyers 有负数就整行拎出来。对缺失的 buyers我的处理原则是先问当事人 18 点到底有没有人买问不到就保留 NaN而不是用前后均值插值。客流有天然峰谷线性插值会把“晚高峰断档”这种最关键的信号平滑掉。4. 小时热力图与转化曲线用 matplotlib 定位业务高峰4.1 折线先看整体趋势客流和购买曲线叠在一起数据清洗完第一张图必须是“客流 购买人数”的双线图一眼能看出哪个时段人多但没人买哪个时段成交效率高import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.plot(df[hour], df[traffic], markero, label客流量) plt.plot(df[hour], df[buyers], markers, label购买顾客数) plt.xticks(df[hour]) plt.xlabel(营业时间) plt.ylabel(人数) plt.legend() plt.savefig(hourly_flow.png, dpi150) plt.show()markero和markers只是让点更清晰dpi150保证保存的图片在放大后依然清晰。观察两条线的间距间距大的时段就是“高流量低转化”适合安排导购重点推荐两条线接近的时段则是成交集中的黄金时段促销资源可以往这里倾斜。4.2 热力图定位周内规律透视表 seaborn单日数据只能看“一天内的高峰”攒了一周数据后就要用热力图看“星期几”和“几点”叠加的规律。先把长表转成宽表矩阵import seaborn as sns pivot pd.pivot_table( df, indexdate, columnshour, valuestraffic, aggfuncsum ) sns.heatmap(pivot, cmapYlOrRd, annotTrue, fmtg) plt.xlabel(营业时间) plt.ylabel(日期) plt.tight_layout() plt.savefig(traffic_heatmap.png, dpi150)pivot_table的index是行维度columns是列维度values是要聚合的指标aggfuncsum表示同一个日期的相同小时出现多次时相加。annotTrue会在格子里显示具体数值fmtg防止大数字变成科学计数法。观察热力图中颜色连续偏红的区域那才是真正值得增加人手和备货的时间窗口单日折线图看不出来。4.3 把结论回填到原始调查表分析完不能只留在图表里我会把每小时汇总写回一个 Excel 工作簿作为原始 doc 的“数字化副本”summary df.groupby(hour)[[traffic, buyers]].sum() summary[conversion] summary[buyers] / summary[traffic] * 100 summary.round(1).to_excel(flow_summary.xlsx, sheet_name小时汇总)round(1)控制在 Excel 里展示的小数位sheet_name指定工作表名。这样做的好处是保留原始 doc 纸张存档的同时给店长一份可直接筛选、排序的汇总表方便月底复盘。5. 批量生成多商品调查表一个 docx 模板复用技巧原表只示例了羊毛衫一个商品实际门店有好几个品类。与其复制粘贴多个 doc不如把原表转成 docx 模板用脚本批量生成from docx import Document products [羊毛衫, 羽绒服, 牛仔裤] for product in products: doc Document(顾客流量调查表_template.docx) table doc.tables[0] table.cell(1, 0).text product doc.save(f顾客流量调查表_{product}.docx)soffice --headless --convert-to docx 顾客流量调查表.doc --outdir templates\customer_template.docx注意table.cell(1, 0)的行号取决于原始模板是否有合并单元格。如果生成后发现商品名写错了位置先打印len(table.rows)和len(table.columns)检查表结构再调整行索引。批量文件生成后可以沿用第 3 章的清洗逻辑把多个商品文件合并成一张大宽表import glob frames [] for path in glob.glob(flow_data/*.xlsx): df_item pd.read_excel(path, header0) frames.append(df_item) all_data pd.concat(frames, ignore_indexTrue) all_data.groupby(product)[buyers].sum().sort_values(ascendingFalse)这段代码把每个商品调查表当作一个独立数据源pd.concat按行拼接ignore_indexTrue重建索引。最后按商品汇总购买人数排序就能直接看出哪个品类贡献了最多成交。把这个结果和客流数据 join 在一起还能进一步算分商品转化率。整个流程从一张纸质 doc 表开始到批量生成、自动合并结束在可复现的数据验证上下次拿到新一天的表只要丢进flow_data目录重跑一遍即可。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价