电商(计算器)数据分析工具

查看 100|回复 11
作者:hfol85   
之前一个坛友要的工具,大概写了一下,可以直接导入表格数据并进行一键分析,将代码,演示数据,分析结果都上传,需对照取数。


image.png (73.51 KB, 下载次数: 0)
下载附件
2024-12-31 23:00 上传

[Python] 纯文本查看 复制代码import tkinter as tk
from tkinter import filedialog, ttk
import pandas as pd
from typing import Dict, Optional
from pathlib import Path
from datetime import datetime
import os
class ExcelDataAnalyzer:
    # 类常量定义
    WINDOW_TITLE = "Excel数据浏览器与分析器"
    WINDOW_SIZE = "800x1000"
    BUTTON_STYLE = {
        'foreground': 'black',
        'background': 'lightblue',
        'font': ('Arial', 10, 'bold')
    }
    EXPORT_FOLDER = "数据分析结果"
   
    def __init__(self, root: tk.Tk):
        self.root = root
        self.root.title(self.WINDOW_TITLE)
        self.root.geometry(self.WINDOW_SIZE)
        self.data: Optional[pd.DataFrame] = None
        self.setup_ui()
    def setup_ui(self):
        """设置UI布局"""
        self._configure_root()
        main_frame = self._create_main_frame()
        self._setup_buttons(main_frame)
        self._setup_date_selectors(main_frame)
        self._setup_labels(main_frame)
    def _configure_root(self):
        """配置根窗口布局"""
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_columnconfigure(0, weight=1)
    def _create_main_frame(self) -> ttk.Frame:
        """创建主框架"""
        main_frame = ttk.Frame(self.root)
        main_frame.grid(sticky='nsew', padx=10, pady=10)
        return main_frame
    def _setup_buttons(self, main_frame: ttk.Frame):
        """设置按钮"""
        button_style = ttk.Style()
        button_style.configure('TButton', **self.BUTTON_STYLE)
        self.open_button = ttk.Button(
            main_frame,
            text="打开Excel文件",
            command=self.open_file,
            style='TButton'
        )
        self.open_button.grid(row=0, column=0, pady=20, sticky='w')
        self.analyze_button = ttk.Button(
            main_frame,
            text="分析数据",
            command=self.analyze_data,
            style='TButton'
        )
        self.analyze_button.grid(row=5, column=0, pady=20, sticky='w')
        self.export_button = ttk.Button(
            main_frame,
            text="导出分析结果",
            command=self.export_results,
            style='TButton'
        )
        self.export_button.grid(row=5, column=1, pady=20, padx=10, sticky='w')
    def open_file(self):
        """打开Excel文件并加载数据"""
        try:
            file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
            if not file_path:
                self.file_label.config(text="未选择文件")
                return
            self.data = pd.read_excel(file_path)
            self.file_label.config(text=f"已选择文件:{Path(file_path).name}")
            self._update_date_menus()
        except Exception as e:
            self.file_label.config(text=f"文件读取错误: {str(e)}")
    def _update_date_menus(self):
        """更新日期选择菜单"""
        if self.data is not None and '日期' in self.data.columns:
            dates = self.data['日期'].dt.strftime('%Y-%m-%d').tolist()
            self.date_var.set(dates[0])
            self.date_menu['values'] = dates
            self.end_date_menu['values'] = dates
    def analyze_data(self):
        """分析数据入口点"""
        if self.data is None:
            self.result_label.config(text="请先选择文件")
            return
        start_date = self.date_var.get()
        end_date = self.end_date_var.get() or start_date
        self.handle_date_range(start_date, end_date)
    def calculate_and_display(self, date_data: pd.DataFrame):
        """计算并显示结果"""
        try:
            results = self._calculate_metrics(date_data)
            self._current_results = results  # 保存当前分析结果
            self.display_results(results)
        except Exception as e:
            self.result_label.config(text=f"计算错误: {str(e)}")
            self._current_results = None
    def _calculate_metrics(self, date_data: pd.DataFrame) -> Dict[str, float]:
        """计算所有指标"""
        try:
            # 基础数据获取
            impressions = date_data['展现量'].sum()
            clicks = date_data['点击量'].sum()
            customer_price = date_data['客单价'].mean()
            conversion_rate = date_data['转化率'].mean()
            revenue = date_data['营业额'].sum()
            uv = date_data['UV'].sum()
            promotion_cost = date_data['推广花费'].sum()
            next_bid = date_data['下一名出价'].mean()
            next_quality_score = date_data['下一名质量得分'].mean()
            quality_score = date_data['质量得分'].mean()
            profit_per_sale = date_data['成交一笔的利润'].mean()
            required_traffic_per_sale = date_data['成交一笔所需的流量'].mean()
            bid = date_data['出价'].mean()
            direct_cost = date_data['直通车花费'].sum()
            gross_margin = date_data['毛利率'].mean()
            daily_sales_amount = date_data['当日成交金额'].sum()
            cpc = date_data['平均点击费用'].mean()
            # 计算各项指标
            click_rate = (clicks / impressions * 100) if impressions else 0
            traffic = impressions * (click_rate / 100)
            sales = traffic * customer_price * conversion_rate
            uv_value = revenue / uv if uv else 0
            pv_value = uv_value * (click_rate / 100)
            roi = sales / promotion_cost if promotion_cost else 0
            actual_cost = next_bid * next_quality_score * quality_score + 0.01
            traffic_value = profit_per_sale / required_traffic_per_sale if required_traffic_per_sale else 0
            number_of_sales = conversion_rate * traffic
            direct_ranking = bid * quality_score
            traffic2 = direct_cost / cpc if cpc else 0
            profit = revenue * gross_margin
            direct_benefit = daily_sales_amount * gross_margin - direct_cost
            direct_display = clicks / (click_rate / 100) if click_rate else 0
            average_click_cost_ppc = direct_cost / clicks if clicks else 0
            average_click_cost_cpc = direct_cost / clicks if clicks else 0
            cost = average_click_cost_ppc * clicks
            return {
                "销售额": sales,
                "流量": traffic,
                "点击率": click_rate,
                "UV价值": uv_value,
                "PV价值": pv_value,
                "ROI": roi,
                "实际扣费": actual_cost,
                "流量价值": traffic_value,
                "成交笔数": number_of_sales,
                "直通车排名": direct_ranking,
                "营业额": revenue,
                "流量2": traffic2,
                "利润": profit,
                "直通车效益": direct_benefit,
                "直通车展现量": direct_display,
                "平均点击花费(PPC)": average_click_cost_ppc,
                "平均点击费用(CPC)": average_click_cost_cpc,
                "花费": cost
            }
        except Exception as e:
            self._current_results = None
            raise Exception(f"计算指标时出错: {str(e)}")
    def display_results(self, results: Dict[str, float]):
        """显示计算结果"""
        for key, value in results.items():
            if key in self.labels:
                self.labels[key].config(text=f"{key}:{value:.2f}")
    def _setup_date_selectors(self, main_frame: ttk.Frame):
        """设置日期选择器"""
        # 文件标签
        self.file_label = ttk.Label(main_frame, text="未选择文件", font=('Arial', 10))
        self.file_label.grid(row=1, column=0, pady=10, sticky='w')
        # 开始日期选择器
        self.date_var = tk.StringVar(self.root)
        self.date_menu = ttk.Combobox(
            main_frame,
            textvariable=self.date_var,
            state='readonly'
        )
        self.date_menu.grid(row=2, column=0, pady=10, sticky='w')
        # 结束日期选择器
        self.end_date_var = tk.StringVar(self.root)
        self.end_date_menu = ttk.Combobox(
            main_frame,
            textvariable=self.end_date_var,
            state='readonly'
        )
        self.end_date_menu.grid(row=3, column=0, pady=10, sticky='w')
    def _setup_labels(self, main_frame: ttk.Frame):
        """设置结果显示标签"""
        # 结果标签
        self.result_label = ttk.Label(
            main_frame,
            text="",
            wraplength=400,
            font=('Arial', 10)
        )
        self.result_label.grid(row=6, column=0, pady=10, sticky='w')
        # 创建标签框架
        labels_frame = ttk.Frame(main_frame)
        labels_frame.grid(row=7, column=0, pady=10, sticky='w')
        # 初始化所有指标标签
        self.labels = {
            "销售额": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "流量": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "点击率": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "UV价值": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "PV价值": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "ROI": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "实际扣费": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "流量价值": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "成交笔数": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "直通车排名": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "营业额": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "流量2": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "利润": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "直通车效益": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "直通车展现量": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "平均点击花费(PPC)": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "平均点击费用(CPC)": ttk.Label(labels_frame, text="", font=('Arial', 10)),
            "花费": ttk.Label(labels_frame, text="", font=('Arial', 10))
        }
        # 布局所有标签
        for index, (label, widget) in enumerate(self.labels.items()):
            widget.grid(row=index, column=0, pady=5, sticky='w')
    def handle_date_range(self, start_date: str, end_date: str):
        """处理日期范围的数据分析"""
        if start_date and end_date:
            if start_date > end_date:
                self.result_label.config(text="开始日期应在结束日期之前")
                return
            date_data = self.data[
                (self.data['日期'] >= pd.to_datetime(start_date)) &
                (self.data['日期']  end_date:
                self.result_label.config(text="开始日期应在结束日期之前")
                return
            # 创建导出文件夹
            if not os.path.exists(self.EXPORT_FOLDER):
                os.makedirs(self.EXPORT_FOLDER)
            # 生成文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"数据分析_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}_{timestamp}.xlsx"
            filepath = os.path.join(self.EXPORT_FOLDER, filename)
            # 存储每天的分析结果
            daily_results = []
            
            # 遍历日期范围内的每一天
            current_date = start_date
            while current_date  max_length:
                                    max_length = len(str(cell.value))
                            except:
                                pass
                        adjusted_width = (max_length + 2)
                        worksheet.column_dimensions[column[0].column_letter].width = adjusted_width
            self.result_label.config(text=f"分析结果已导出到:{filepath}")
            
        except Exception as e:
            self.result_label.config(text=f"导出失败:{str(e)}")
    def _calculate_summary(self, daily_data: pd.DataFrame) -> Dict[str, float]:
        """计算区间汇总数据"""
        summary = {}
        
        # 需要求和的指标
        sum_metrics = [
            "销售额", "营业额", "利润", "直通车效益", "花费",
            "直通车展现量", "流量", "流量2", "成交笔数"
        ]
        
        # 需要求平均的指标
        avg_metrics = [
            "点击率", "UV价值", "PV价值", "ROI", "实际扣费",
            "流量价值", "直通车排名", "平均点击花费(PPC)",
            "平均点击费用(CPC)"
        ]
        
        # 计算汇总值
        for metric in sum_metrics:
            if metric in daily_data.columns:
                summary[metric] = daily_data[metric].sum()
               
        for metric in avg_metrics:
            if metric in daily_data.columns:
                summary[metric] = daily_data[metric].mean()
        
        return summary
if __name__ == "__main__":
    root = tk.Tk()
    app = ExcelDataAnalyzer(root)
    root.mainloop()

演示数据 - 副本.rar
(10 KB, 下载次数: 65)
2024-12-31 22:57 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB


数据分析_20240101_20240106_20241230_212516.rar
(6.95 KB, 下载次数: 89)
2024-12-31 22:58 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB

日期, 数据

hfol85
OP
  


yinhuazuimeng 发表于 2025-1-9 20:57
是的  它应该是去年就过期了   我发现它是按照系统时间来判断是否过期的 所以用了一个可以欺骗wps的软件 ...

这是根据你给我原始数据和文件写成的程序最终的使用界面,后面还导出了分析结果的数据。不知道是不是你想要的那种效果。


1736477119721.jpg (41.32 KB, 下载次数: 0)
下载附件
2025-1-10 10:46 上传



1736477143166.jpg (93.7 KB, 下载次数: 0)
下载附件
2025-1-10 10:46 上传



1736477153311.jpg (56.95 KB, 下载次数: 0)
下载附件
2025-1-10 10:47 上传


Desktop.rar
(26.98 KB, 下载次数: 11)
2025-1-10 10:48 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB

cfl300   

电商现在只有头部玩家玩得过来,普通人去买所谓的流量不等于把钱扔海里。。。平台现在是套路越来越多
hfol85
OP
  


yinhuazuimeng 发表于 2025-1-11 00:19
那可太好了  真是无比感谢!

链接:https://pan.baidu.com/s/1kpfyUONti2WtZz4gjosRQA?pwd=52pj 求好评哦
52wjj   

感谢分享
wuyongjun   

应该是用的吧
R9527   

感谢分享
龍謹   

电商用的,很有针对性哦,偶来学习PY代码。
lizhenguogouw   

对销售人员很有用
echoofw   

感谢分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部