当前位置:首页>python>使用Python 和 Streamlit 构建的多维度游戏玩家数据分析

使用Python 和 Streamlit 构建的多维度游戏玩家数据分析

  • 2026-03-26 17:51:57
使用Python 和 Streamlit 构建的多维度游戏玩家数据分析

游戏玩家数据分析与可视化

概述

这是一个基于 Python 和 Streamlit 构建的多维度游戏玩家数据分析应用。项目旨在为游戏运营团队提供一个全面、交互式的数据分析工具,通过12个核心维度深度剖析玩家行为,帮助制定科学的运营策略,提升玩家留存和付费转化。

目标

    数据洞察:从海量玩家数据中提取有价值的信息

    用户分群:精细化识别不同类型玩家特征

    预测分析:提前识别潜在流失风险和高价值用户

    决策支持:基于数据提供可执行的运营建议

架构

技术栈全景

┌─────────────────────────────────────────────┐│         前端界面层 (UI Layer)                ││  ┌─────────────────────────────────────┐    ││  │  Streamlit + Custom CSS + Plotly    │    ││  └─────────────────────────────────────┘    │├─────────────────────────────────────────────┤│          业务逻辑层 (Logic Layer)            ││  ┌─────────────────────────────────────┐    ││  │  Pandas + NumPy + Scikit-learn      │    ││  │  + 数据分析算法 + 预测模型           │    ││  └─────────────────────────────────────┘    │├─────────────────────────────────────────────┤│          数据处理层 (Data Layer)             ││  ┌─────────────────────────────────────┐    ││  │  CSV文件处理 + 数据预处理             ││  │  + 特征工程 + 缓存机制               ││  └─────────────────────────────────────┘    │├─────────────────────────────────────────────┤│          基础设施层 (Infrastructure)         ││  ┌─────────────────────────────────────┐    ││  │  Python 3.10+ + 依赖管理系统        ││  │  + 开发环境配置                     ││  └─────────────────────────────────────┘    │└─────────────────────────────────────────────┘

详细技术栈配置

技术类别	具体组件	版本	主要用途前端框架	Streamlit	1.28.0	构建交互式Web界面数据处理	Pandas	2.1.4	数据加载、清洗、转换数值计算	NumPy	1.24.3	数值运算、数组处理可视化	Plotly	5.17.0	交互式图表、3D可视化机器学习	Scikit-learn	1.3.2	聚类分析、预测模型可选依赖	Seaborn	0.13.0	统计可视化(降级可用)系统支持	Python	3.10+	运行环境

结构设计

1. 原始数据字段 (12个维度)

字段名称	数据类型	说明	示例用户IDInteger	玩家唯一标识	100001玩家性别	String	性别信息	男/女玩家年龄	Integer	实际年龄	27所在区域	String	地理位置	华东/华南/华北游戏段位	String	竞技水平	荣耀青铜/最强王者日均时长	Float	平均每日游戏时长(小时)	3.9累计消费	Float	历史总消费金额(元)	22.41擅长位置	String	游戏角色偏好	坦克/刺客/辅助综合胜率	Float	胜率(0-1)	0.483KDA指数	Float	击杀/死亡/助攻综合评分	5.4登录频率	String	活跃度指标	每天/每周3-5行为模式	String	玩家类型标识	竞技型/社交型

2. 衍生字段设计(通过特征工程生成)

特征工程架构

# 数据预处理函数 - 特征工程核心

def preprocess_data(df):    # 1. 离散化处理    df['消费分段'] = pd.cut(df['累计消费'], bins=[0, 20, 100, float('inf')],                            labels=['低消费''中消费''高消费'])    df['年龄分段'] = pd.cut(df['玩家年龄'], bins=[0, 18, 25, 30, 100],                           labels=['青少年''青年''成年''中老年'])    # 2. 编码转换    rank_order = ['荣耀青铜''秩序白银''尊贵铂金''永恒钻石''至尊星耀''最强王者']    df['段位等级'] = df['游戏段位'].map({r: i+1 for i, r in enumerate(rank_order)})    # 3. 复合特征    df['活跃度分数'] = (df['登录频率等级'] * 0.6 +                        df['日均时长'] / df['日均时长'].max() * 0.4)    # 4. 分群标签    df['活跃度分段'] = pd.qcut(df['活跃度分数'], q=[0, 0.33, 0.66, 1],                              labels=['流失用户''普通用户''核心用户'])    return df

衍生字段详情

衍生字段	生成方法	业务含义	数据类型消费分段	pd.cut(累计消费)	玩家付费能力等级	Categorical年龄分段	pd.cut(玩家年龄)	年龄段分布	Categorical段位等级	有序编码映射	竞技水平量化	Integer登录频率等级	频率编码	活跃度量化	Integer活跃度分数	加权计算(0.6登录等级+0.4时长标准化)	综合活跃度评分	Float活跃度分段	pd.qcut(活跃度分数)	活跃度分群标签	Categorical技能分数	0.4段位等级+0.3胜率100+0.3KDA标准化	综合技能评分	Float技能分段	pd.qcut(技能分数)	技能水平分群	Categorical流失风险	规则模型预测	流失可能性评分	Float流失风险等级	pd.cut(流失风险)	流失风险等级	Categorical付费潜力	规则模型预测	未来付费可能性	Categorical预计晋升时间	规则模型预测	段位提升时间估计	Categorical用户价值分	0.5消费+0.3活跃度+0.2*技能	综合价值评分	Float

功能详解

模块一:用户画像分析

1.1 人口统计画像

    性别分布:饼图展示男女比例

    年龄分段:条形图展示各年龄段人数

    区域分布:柱状图展示各地区用户数量

1.2 游戏能力画像

    段位分布:条形图展示各段位用户数

    位置偏好:饼图展示不同位置玩家比例

    KDA分布:直方图展示技能水平

    胜率分布:直方图展示胜负情况

1.3 行为习惯画像

    登录频率:条形图展示活跃频率

    行为模式:饼图展示玩家类型

    日均时长:直方图展示游戏时长习惯

1.4 消费能力画像

    消费分段:饼图展示高/中/低消费比例

    累计消费:直方图展示消费金额分布

模块二:用户细分分析

2.1 价值分群

    高消费用户:累计消费>100元

    中消费用户:20元<累计消费≤100元

    低消费用户:累计消费≤20元

2.2 活跃度分群

    核心用户:活跃度分数前33%

    普通用户:活跃度分数中间34%

    流失用户:活跃度分数后33%

2.3 技能分群

    高手:技能分数前33%

    进阶玩家:技能分数中间34%

    新手:技能分数后33%

2.4 偏好分群

    基于擅长位置分析消费分布

    识别不同位置偏好的用户特征

2.5 行为分群

    按行为模式分析段位和消费分布

    识别竞技型、社交型、休闲型玩家特征

模块三:关联与相关性分析

3.1 消费驱动因素分析

    时长vs消费:散点图分析游戏时长与消费关系

    段位vs消费:箱线图分析不同段位消费分布

    胜率vs消费:散点图分析胜率与消费关联

3.2 活跃度影响因素

    年龄vs登录频率:热力图分析年龄与活跃度关系

    区域vs登录频率:热力图分析区域与活跃度关联

3.3 技能成长路径

    时长vsKDA:散点图分析游戏时长与技能关系

    段位vsKDA:箱线图分析不同段位技能水平

3.4 区域差异分析

    区域消费对比:柱状图展示各地区平均消费

    区域活跃度:柱状图展示各地区游戏时长

    区域段位分布:热力图分析各地区段位特征

模块四:预测性分析

4.1 用户流失预测模型

def predict_churn_risk(row):    """基于规则的流失风险预测"""    login_score = {'每月几次'3'每周1-2次'2'每周3-5次'1'每天'0}    behavior_score = {'娱乐型'1'休闲型'2'社交型'3'收藏型'2'竞技型'4}    risk = (login_score.get(row['登录频率'], 2) * 0.4 +            (1 if row['日均时长'] < 2 else 0) * 0.3 +            behavior_score.get(row['行为模式'], 2) * 0.3)    return min(risk, 3)

4.2 付费潜力预测

    高潜力:累计消费>100元

    中潜力:20元<累计消费≤100元

    低潜力:累计消费≤20元

4.3 段位晋升时间预测

    1-2周:KDA>4且胜率>0.55

    2-4周:KDA>3且胜率>0.5

    4-8周:其他情况

模块五:运营决策支持

5.1 高价值用户识别

    TOP10用户:基于用户价值分排序

    价值分布:识别高价值用户特征

    专属福利策略:针对高价值用户制定个性化方案

5.2 流失预警干预

    高风险用户识别:流失风险等级=高风险

    召回策略:针对不同类型用户的召回方案

    个性化推送:基于行为模式的定向内容

5.3 匹配优化建议

    段位平衡算法:优化对战匹配机制

    技能权重调整:综合胜率、KDA、时长多维度

    新手保护机制:根据游戏时长调整匹配范围

5.4 内容推荐策略

    位置偏好推荐:基于擅长位置的个性化内容

    行为模式推荐:针对不同类型玩家的差异化推荐

    消费能力推荐:基于消费分段的商品推荐

5.5 定价策略分析

    区域差异定价:基于各地区平均消费水平

    分层定价模型:基础版/进阶版/豪华版策略

    促销活动优化:根据不同用户特征制定促销方案

模块六:可视化分析

6.1 用户分布分析

    区域热力图:展示各地区用户分布密度

    年龄/段位金字塔:金字塔图展示用户结构

6.2 趋势分析

    登录频率趋势:折线图展示活跃度变化

    日均时长分布:柱状图展示游戏时长趋势

6.3 对比分析

    性别消费对比:柱状图对比男女消费差异

    区域活跃度对比:柱状图对比各地区游戏时长

6.4 关联分析

    多维度散点图:时长vs消费、胜率vsKDA

    3D散点图:时长、消费、胜率三维关联分析

6.5 分群分析

    雷达图分群对比:各行为模式用户画像对比

    标准化对比图:多维度标准化后的对比分析

关键技术实现

1. 数据预处理优化

1.1 特征工程策略

class FeatureEngineer:    def __init__(self):        self.rank_mapping = None        self.login_mapping = None    def fit(self, df):        """学习特征转换规则"""        # 段位有序编码        rank_order = ['荣耀青铜''秩序白银''尊贵铂金''永恒钻石''至尊星耀''最强王者']        self.rank_mapping = {r: i+1 for i, r in enumerate(rank_order)}        # 登录频率有序编码        login_order = ['每月几次''每周1-2次''每周3-5次''每天']        self.login_mapping = {l: i+1 for i, l in enumerate(login_order)}    def transform(self, df):        """应用特征转换"""        df_transformed = df.copy()        # 离散化特征        df_transformed['消费分段'] = pd.cut(df['累计消费'],                                           bins=[020100float('inf')],                                          labels=['低消费''中消费''高消费'])        # 有序编码        df_transformed['段位等级'] = df['游戏段位'].map(self.rank_mapping)        df_transformed['登录频率等级'] = df['登录频率'].map(self.login_mapping)        # 复合特征        df_transformed = self._create_composite_features(df_transformed)        return df_transformed

1.2 缓存机制优化

@st.cache_data(ttl=3600, max_entries=5)def load_data(file):    """带缓存的数据加载"""    df = pd.read_csv(file)    # 数据类型转换    numeric_columns = ['日均时长''累计消费''综合胜率''KDA指数''玩家年龄']    for col in numeric_columns:        df[col] = pd.to_numeric(df[col], errors='coerce')    return df

2. 可视化架构

2.1 响应式图表系统

class ResponsiveChartSystem:    def __init__(self):        self.theme = 'plotly_white'    def create_scatter_matrix(self, df, dimensions, color_col=None):        """创建响应式散点矩阵"""        fig = px.scatter_matrix(df,                                dimensions=dimensions,                                color=color_col,                                title="多维关联分析矩阵",                                opacity=0.7,                                template=self.theme)        # 自适应调整        fig.update_traces(diagonal_visible=True)        fig.update_layout(height=800)        return fig    def create_animated_timeline(self, df, time_col, value_cols):        """创建动画时间线"""        fig = px.line(df, x=time_col, y=value_cols,                     title="时间趋势分析",                     template=self.theme)        fig.update_layout(            hovermode='x unified',            xaxis=dict(title="时间轴"),            yaxis=dict(title="指标值")        )        return fig

2.2 交互式组件

class InteractiveComponents:    def __init__(self):        self.filters = {}    def create_dynamic_filter(self, df, column_name):        """创建动态过滤器"""        unique_values = df[column_name].unique()        filter_widget = st.multiselect(            f"筛选 {column_name}",            options=unique_values,            default=unique_values[:5if len(unique_values) > 5 else unique_values        )        self.filters[column_name] = filter_widget        return filter_widget    def apply_filters(self, df):        """应用过滤器"""        filtered_df = df.copy()        for col, values in self.filters.items():            if values:                filtered_df = filtered_df[filtered_df[col].isin(values)]        return filtered_df

3. 机器学习应用

3.1 K-means聚类分析

class PlayerClustering:    def __init__(self, n_clusters=4):        self.n_clusters = n_clusters        self.scaler = StandardScaler()        self.kmeans = KMeans(n_clusters=n_clusters, random_state=42)        self.cluster_labels = None    def fit_transform(self, df):        """聚类分析"""        # 特征选择        features = ['段位等级''日均时长''累计消费''综合胜率''KDA指数']        X = df[features].fillna(0)        # 标准化        X_scaled = self.scaler.fit_transform(X)        # K-means聚类        self.cluster_labels = self.kmeans.fit_predict(X_scaled)        # 分析聚类特征        self._analyze_clusters(df, self.cluster_labels)        return self.cluster_labels

3.2 预测模型架构

class PredictiveModels:    def __init__(self):        self.churn_model = RandomForestClassifier()        self.value_model = RandomForestRegressor()    def train_churn_model(self, X_train, y_train):        """训练流失预测模型"""        X_train_encoded = self._encode_features(X_train)        self.churn_model.fit(X_train_encoded, y_train)        # 模型评估        scores = cross_val_score(self.churn_model, X_train_encoded, y_train, cv=5)        return scores.mean()    def predict_user_value(self, user_features):        """预测用户价值"""        return self.value_model.predict([user_features])[0]

UI/UX 设计架构

1. 视觉设计系统

1.1 色彩体系

/* 主色调 - 游戏科技感 */:root {  --primary-gradientlinear-gradient(135deg#667eea 0%#764ba2 100%);  --success-gradientlinear-gradient(135deg#2ecc71 0%#27ae60 100%);  --warning-gradientlinear-gradient(135deg#f39c12 0%#e74c3c 100%);  --info-gradientlinear-gradient(135deg#3498db 0%#2c3e50 100%);}

1.2 组件设计规范

class UIConstants:    # 字体系统    FONT_PRIMARY = "'Segoe UI', 'Microsoft YaHei', sans-serif"    HEADER_FONT_SIZE = "3rem"    SECTION_FONT_SIZE = "1.8rem"    # 间距系统    SPACING_UNIT = "15px"    SECTION_MARGIN = "25px"    CARD_PADDING = "20px"    # 圆角系统      BORDER_RADIUS_SM = "10px"    BORDER_RADIUS_MD = "15px"    BORDER_RADIUS_LG = "20px"

2. 布局系统

2.1 响应式布局

class LayoutManager:    def __init__(self):        self.breakpoints = {            'xs'576,            'sm'768,            'md'992,            'lg'1200        }    def create_responsive_columns(self, num_cols):        """创建响应式列布局"""        col_widths = [f"{100/num_cols}%" for _ in range(num_cols)]        return st.columns(col_widths)    def adaptive_grid(self, items, cols_per_row=3):        """自适应网格布局"""        rows = (len(items) + cols_per_row - 1) // cols_per_row        for row in range(rows):            cols = st.columns(cols_per_row)            start_idx = row * cols_per_row            end_idx = min(start_idx + cols_per_row, len(items))            for i, item in enumerate(items[start_idx:end_idx]):                with cols[i]:                    # 渲染项目                    pass

3. 交互设计

3.1 用户流设计

用户流程:

1. 打开应用 → 2. 上传数据 → 3. 查看总览指标 → 4. 选择分析模块   ↓5. 交互式分析 → 6. 查看可视化 → 7. 获取建议 → 8. 导出结果

3.2 反馈机制

class FeedbackSystem:    def show_loading_state(self):        """显示加载状态"""        with st.spinner("正在处理数据..."):            # 执行耗时操作            pass    def show_progress_bar(self, current, total, label="进度"):        """显示进度条"""        progress = current / total        st.progress(progress, text=f"{label}{current}/{total}")    def show_notification(self, message, level="info"):        """显示通知"""        if level == "success":            st.success(message)        elif level == "warning":            st.warning(message)        elif level == "error":            st.error(message)        else:            st.info(message)

部署

1. 环境配置

1.1 依赖管理

# requirements.txt 详细说明streamlit==1.28.0          # 核心Web框架pandas==2.1.4              # 数据处理numpy==1.24.3              # 数值计算plotly==5.17.0             # 交互式可视化scikit-learn==1.3.2        # 机器学习seaborn==0.13.0            # 统计可视化(可选)# 环境设置脚本python -m venv venvsource venv/bin/activate   # Linux/Macvenv\Scripts\activate      # Windowspip install -r requirements.txt

1.2 配置管理

# config.pyimport osfrom pathlib import Pathclass AppConfig:    # 路径配置    BASE_DIR = Path(__file__).parent    DATA_DIR = BASE_DIR / "data"    # 应用配置    APP_TITLE = "游戏玩家数据分析平台"    APP_ICON = "🎮"    LAYOUT = "wide"    # 数据处理配置    CACHE_TTL = 3600  # 缓存时间(秒)    MAX_ROWS = 10000  # 最大处理行数    @classmethod    def setup_directories(cls):        """创建必要的目录"""        os.makedirs(cls.DATA_DIR, exist_ok=True)

2. 性能优化

2.1 数据缓存策略

class CacheManager:    def __init__(self, ttl=3600):        self.cache = {}        self.ttl = ttl    def get_or_compute(self, key, compute_func):        """缓存或计算数据"""        if key in self.cache:            cached_item = self.cache[key]            if time.time() - cached_item['timestamp'] < self.ttl:                return cached_item['data']        # 计算并缓存        data = compute_func()        self.cache[key] = {            'data': data,            'timestamp': time.time()        }        return data

2.2 内存优化

class MemoryOptimizer:    @staticmethod    def optimize_dataframe(df):        """优化DataFrame内存使用"""        df_optimized = df.copy()        # 数值类型优化        for col in df.select_dtypes(include=['int64']).columns:            df_optimized[col] = pd.to_numeric(df[col], downcast='integer')        # 字符串类型优化        for col in df.select_dtypes(include=['object']).columns:            df_optimized[col] = df[col].astype('category')        return df_optimized

3. 监控与日志

3.1 日志系统

import loggingclass LoggingSystem:    def __init__(self, log_level=logging.INFO):        logging.basicConfig(            level=log_level,            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',            handlers=[                logging.FileHandler('app.log'),                logging.StreamHandler()            ]        )        self.logger = logging.getLogger(__name__)    def log_performance(self, operation, duration):        """记录性能日志"""        self.logger.info(f"{operation} 完成,耗时: {duration:.2f}秒")    def log_data_stats(self, df):        """记录数据统计日志"""        self.logger.info(f"数据形状: {df.shape}")        self.logger.info(f"列: {list(df.columns)}")

3.2 监控指标

class PerformanceMonitor:    def __init__(self):        self.metrics = {            'data_loading_time': [],            'preprocessing_time': [],            'analysis_time': []        }    def track_performance(self, metric_name, duration):        """跟踪性能指标"""        if metric_name in self.metrics:            self.metrics[metric_name].append(duration)            # 记录统计信息            avg_time = np.mean(self.metrics[metric_name])            self._log_metric(metric_name, duration, avg_time)    def get_performance_report(self):        """生成性能报告"""        report = {}        for metric, values in self.metrics.items():            if values:                report[metric] = {                    'count'len(values),                    'avg': np.mean(values),                    'min': np.min(values),                    'max': np.max(values)                }        return report

代码

import streamlit as stimport pandas as pdimport numpy as npimport plotly.express as pximport plotly.graph_objects as gofrom plotly.subplots import make_subplotsfrom sklearn.preprocessing import StandardScalerLabelEncoderfrom sklearn.cluster import KMeansfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import train_test_splitimport warningswarnings.filterwarnings('ignore')# 可选导入seaborntry:    import seaborn as sns    seaborn_available = Trueexcept ImportError:    seaborn_available = False    # 提供一个替代的sns模块占位符    class SnsStub:        def __getattr__(self, name):            def stub_function(*args, **kwargs):                # 静默返回None或空值                return None            return stub_function    sns = SnsStub()# 页面配置st.set_page_config(page_title="游戏玩家数据分析平台", page_icon="🎮", layout="wide")# 自定义CSSst.markdown("""<style>    .main-header {        font-size: 3rem;        font-weight: 800;        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);        -webkit-background-clip: text;        -webkit-text-fill-color: transparent;        text-align: center;        padding: 30px 0;        margin-bottom: 20px;    }    .metric-card {        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);        padding: 20px;        border-radius: 15px;        color: white;        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);        transition: transform 0.3s ease;    }    .metric-card:hover {        transform: translateY(-5px);    }    .stMetric [data-baseweb="metric-label"] {        color: white;        font-weight: 600;        font-size: 0.9rem;        opacity: 0.9;    }    .stMetric [data-baseweb="metric-value"] {        color: white;        font-size: 2.2rem;        font-weight: 700;    }    .section-header {        font-size: 1.8rem;        font-weight: 700;        color: #2c3e50;        margin: 25px 0 15px 0;        padding-bottom: 10px;        border-bottom: 3px solid #3498db;    }    .info-card {        background: linear-gradient(135deg, #3498db 0%, #2c3e50 100%);        padding: 25px;        border-radius: 15px;        color: white;        margin: 15px 0;        box-shadow: 0 4px 15px rgba(52, 152, 219, 0.2);    }    .warning-card {        background: linear-gradient(135deg, #f39c12 0%, #e74c3c 100%);        padding: 25px;        border-radius: 15px;        color: white;        margin: 15px 0;        box-shadow: 0 4px 15px rgba(243, 156, 18, 0.2);    }    .success-card {        background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);        padding: 25px;        border-radius: 15px;        color: white;        margin: 15px 0;        box-shadow: 0 4px 15px rgba(46, 204, 113, 0.2);    }    .sidebar .sidebar-content {        background: linear-gradient(180deg, #2c3e50 0%, #1a252f 100%);    }    .stSelectbox, .stRadio, .stExpander {        margin-bottom: 15px;    }    .stExpander > div {        border-radius: 10px !important;        border: 1px solid #e0e0e0;        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);    }    .stTab {        margin-top: 20px;    }    .feature-icon {        font-size: 2.5rem;        margin-bottom: 10px;    }    .feature-title {        font-size: 1.3rem;        font-weight: 600;        margin-bottom: 10px;    }    .feature-description {        font-size: 0.95rem;        color: #666;        line-height: 1.5;    }</style>""", unsafe_allow_html=True)# 数据加载与处理@st.cache_datadef load_data(file):    df = pd.read_csv(file)    df['日均时长'] = pd.to_numeric(df['日均时长'], errors='coerce')    df['累计消费'] = pd.to_numeric(df['累计消费'], errors='coerce')    df['综合胜率'] = pd.to_numeric(df['综合胜率'], errors='coerce')    df['KDA指数'] = pd.to_numeric(df['KDA指数'], errors='coerce')    df['玩家年龄'] = pd.to_numeric(df['玩家年龄'], errors='coerce')    return df@st.cache_datadef preprocess_data(df):    df_processed = df.copy()    # 段位编码    rank_order = ['荣耀青铜''秩序白银''尊贵铂金''永恒钻石''至尊星耀''最强王者']    df_processed['段位等级'] = df_processed['游戏段位'].map({r: i+1 for i, r in enumerate(rank_order)})    # 登录频率编码    login_order = ['每月几次''每周1-2次''每周3-5次''每天']    df_processed['登录频率等级'] = df_processed['登录频率'].map({l: i+1 for i, l in enumerate(login_order)})    # 年龄分段    df_processed['年龄分段'] = pd.cut(df_processed['玩家年龄'],                                        bins=[0182530100],                                        labels=['青少年''青年''成年''中老年'])    # 消费分段 - 在预处理阶段创建,确保所有函数都能访问    df_processed['消费分段'] = pd.cut(df_processed['累计消费'],                                      bins=[020100, float('inf')],                                      labels=['低消费''中消费''高消费'])    # 时长分段    df_processed['时长分段'] = pd.cut(df_processed['日均时长'],                                     bins=[0246, float('inf')],                                     labels=['0-2小时''2-4小时''4-6小时''6+小时'])    # 活跃度分数 - 在预处理阶段计算    df_processed['活跃度分数'] = (        df_processed['登录频率等级'] * 0.6 +        (df_processed['日均时长'] / df_processed['日均时长'].max()) * 0.4    )    # 活跃度分段    df_processed['活跃度分段'] = pd.qcut(df_processed['活跃度分数'],                                        q=[00.330.661],                                        labels=['流失用户''普通用户''核心用户'])    # 技能分数    df_processed['技能分数'] = (        df_processed['段位等级'] * 0.4 +        df_processed['综合胜率'] * 100 * 0.3 +        (df_processed['KDA指数'] / df_processed['KDA指数'].max()) * 30    )    # 技能分段    df_processed['技能分段'] = pd.qcut(df_processed['技能分数'],                                      q=[00.330.661],                                      labels=['新手''进阶''高手'])    return df_processeddef calculate_metrics(df):    metrics = {        '总玩家数': len(df),        '平均年龄': round(df['玩家年龄'].mean(), 1),        '平均日均时长': round(df['日均时长'].mean(), 1),        '总累计消费': round(df['累计消费'].sum(), 2),        '平均累计消费': round(df['累计消费'].mean(), 2),        '平均胜率': round(df['综合胜率'].mean() * 1001),        '平均KDA': round(df['KDA指数'].mean(), 1),    }    return metricsdef predict_churn_risk(row):    """预测流失风险评分"""    login_score = {'每月几次'3'每周1-2次'2'每周3-5次'1'每天'0}    behavior_score = {'娱乐型'1'休闲型'2'社交型'3'收藏型'2'竞技型'4}    risk = (login_score.get(row['登录频率'], 2) * 0.4 +            (1 if row['日均时长'] < 2 else 0) * 0.3 +            behavior_score.get(row['行为模式'], 2) * 0.3)    return min(risk, 3)def predict_pay_potential(row):    """预测付费潜力"""    if row['累计消费'] > 100:        return '高'    elif row['累计消费'] > 20:        return '中'    else:        return '低'def predict_promotion_time(row):    """预测段位晋升时间"""    if row['游戏段位'] == '最强王者':        return '已达巅峰'    elif row['KDA指数'] > 4 and row['综合胜率'] > 0.55:        return '1-2周'    elif row['KDA指数'] > 3 and row['综合胜率'] > 0.5:        return '2-4周'    else:        return '4-8周'# 用户画像分析def user_profile_analysis(df, df_processed):    st.markdown("## 📊 用户画像分析")    # 1. 人口统计画像    with st.expander("👥 人口统计画像", expanded=True):        col1, col2, col3 = st.columns(3)        with col1:            gender_dist = df['玩家性别'].value_counts()            fig_gender = px.pie(gender_dist, values=gender_dist.values, names=gender_dist.index,                                 title='玩家性别分布', hole=0.5,                                 color_discrete_sequence=px.colors.qualitative.Set3)            st.plotly_chart(fig_gender, use_container_width=True)        with col2:            age_dist = df_processed['年龄分段'].value_counts().sort_index()            fig_age = px.bar(age_dist, x=age_dist.index, y=age_dist.values,                            title='年龄分段分布',                            labels={'x''年龄段''y''人数'},                            color=age_dist.values,                            color_continuous_scale='Blues')            st.plotly_chart(fig_age, use_container_width=True)        with col3:            region_dist = df['所在区域'].value_counts()            fig_region = px.bar(region_dist, x=region_dist.index, y=region_dist.values,                               title='区域分布',                               labels={'x''区域''y''人数'},                               color=region_dist.values,                               color_continuous_scale='Viridis')            st.plotly_chart(fig_region, use_container_width=True)    # 2. 游戏能力画像    with st.expander("⚔️ 游戏能力画像", expanded=True):        col1, col2 = st.columns(2)        with col1:            rank_dist = df['游戏段位'].value_counts().sort_index()            fig_rank = px.bar(rank_dist, x=rank_dist.index, y=rank_dist.values,                             title='段位分布',                             labels={'x''段位''y''人数'},                             color=rank_dist.values,                             color_continuous_scale='RdYlGn_r')            fig_rank.update_xaxes(tickangle=45)            st.plotly_chart(fig_rank, use_container_width=True)        with col2:            position_dist = df['擅长位置'].value_counts()            fig_position = px.pie(position_dist, values=position_dist.values, names=position_dist.index,                                  title='擅长位置分布', hole=0.4,                                  color_discrete_sequence=px.colors.qualitative.Pastel)            st.plotly_chart(fig_position, use_container_width=True)        # KDA和胜率分布        col1, col2 = st.columns(2)        with col1:            fig_kda = px.histogram(df, x='KDA指数', nbins=50,                                  title='KDA指数分布',                                  color_discrete_sequence=['#3498db'])            st.plotly_chart(fig_kda, use_container_width=True)        with col2:            fig_winrate = px.histogram(df, x='综合胜率', nbins=50,                                      title='综合胜率分布',                                      color_discrete_sequence=['#2ecc71'])            st.plotly_chart(fig_winrate, use_container_width=True)    # 3. 行为习惯画像    with st.expander("🎯 行为习惯画像", expanded=True):        col1, col2, col3 = st.columns(3)        with col1:            login_dist = df['登录频率'].value_counts()            login_order = ['每天''每周3-5次''每周1-2次''每月几次']            login_dist = login_dist.reindex(login_order)            fig_login = px.bar(login_dist, x=login_dist.index, y=login_dist.values,                              title='登录频率分布',                              labels={'x''登录频率''y''人数'},                              color=login_dist.values,                              color_continuous_scale='YlOrRd')            st.plotly_chart(fig_login, use_container_width=True)        with col2:            behavior_dist = df['行为模式'].value_counts()            fig_behavior = px.pie(behavior_dist, values=behavior_dist.values, names=behavior_dist.index,                                  title='行为模式分布', hole=0.5,                                  color_discrete_sequence=px.colors.qualitative.Bold)            st.plotly_chart(fig_behavior, use_container_width=True)        with col3:            fig_duration = px.histogram(df, x='日均时长', nbins=50,                                       title='日均时长分布',                                       color_discrete_sequence=['#9b59b6'])            st.plotly_chart(fig_duration, use_container_width=True)    # 4. 消费能力画像    with st.expander("💰 消费能力画像", expanded=True):        col1, col2 = st.columns(2)        # 直接使用预处理阶段创建的消费分段        spend_dist = df_processed['消费分段'].value_counts()        with col1:            fig_spend = px.pie(spend_dist, values=spend_dist.values, names=spend_dist.index,                              title='消费能力分布', hole=0.5,                              color_discrete_sequence=['#95a5a6', '#f39c12', '#e74c3c'])            st.plotly_chart(fig_spend, use_container_width=True)        with col2:            fig_spend_hist = px.histogram(df, x='累计消费', nbins=50,                                          title='累计消费金额分布',                                          color_discrete_sequence=['#16a085'])            st.plotly_chart(fig_spend_hist, use_container_width=True)# 用户细分分析def segmentation_analysis(df, df_processed):    st.markdown("## 🎯 用户细分/分群分析")    # 1. 按价值分群    with st.expander("💎 按价值分群", expanded=True):        col1, col2 = st.columns(2)        with col1:            spend_segment = df_processed['消费分段'].value_counts()            fig_spend_seg = px.bar(spend_segment, x=spend_segment.index, y=spend_segment.values,                                   title='价值分群(按累计消费)',                                   labels={'x''消费级别''y''人数'},                                   color=spend_segment.index,                                   color_discrete_map={'低消费''#95a5a6', '中消费''#f39c12', '高消费''#e74c3c'})            st.plotly_chart(fig_spend_seg, use_container_width=True)        with col2:            # 高价值用户特征分析            high_value = df_processed[df_processed['消费分段'] == '高消费']            if len(high_value) > 0:                st.markdown("### 高价值用户特征")                col1, col2, col3 = st.columns(3)                with col1:                    st.metric("人数", len(high_value))                with col2:                    st.metric("平均胜率", f"{high_value['综合胜率'].mean()*100:.1f}%")                with col3:                    st.metric("平均KDA", f"{high_value['KDA指数'].mean():.1f}")    # 2. 按活跃度分群    with st.expander("🔥 按活跃度分群", expanded=True):        col1, col2 = st.columns(2)        with col1:            active_dist = df_processed['活跃度分段'].value_counts()            fig_active = px.bar(active_dist, x=active_dist.index, y=active_dist.values,                               title='活跃度分群',                               labels={'x''活跃度级别''y''人数'},                               color=active_dist.values,                               color_continuous_scale='RdYlGn')            st.plotly_chart(fig_active, use_container_width=True)        with col2:            # 活跃度与消费关系            fig_active_spend = px.box(df_processed, x='活跃度分段', y='累计消费',                                     title='不同活跃度用户的消费分布',                                     color='活跃度分段')            st.plotly_chart(fig_active_spend, use_container_width=True)    # 3. 按技能分群    with st.expander("🎮 按技能分群", expanded=True):        col1, col2 = st.columns(2)        with col1:            skill_dist = df_processed['技能分段'].value_counts()            fig_skill = px.pie(skill_dist, values=skill_dist.values, names=skill_dist.index,                              title='技能水平分群', hole=0.5,                              color_discrete_sequence=['#3498db', '#f39c12', '#e74c3c'])            st.plotly_chart(fig_skill, use_container_width=True)        with col2:            # 技能与活跃度关系            fig_skill_active = px.scatter(df_processed, x='技能分数', y='活跃度分数',                                          color='技能分段',                                          title='技能分数 vs 活跃度分数',                                          labels={'技能分数''技能分数''活跃度分数''活跃度分数'},                                          hover_data=['游戏段位''综合胜率'])            st.plotly_chart(fig_skill_active, use_container_width=True)    # 4. 按偏好分群    with st.expander("⭐ 按偏好分群", expanded=True):        # 确保df_processed中有消费分段字段        if '消费分段' in df_processed.columns:            # 创建一个包含擅长位置和消费分段的DataFrame用于分组            temp_df = df_processed[['擅长位置''消费分段']].copy()            position_analysis = temp_df.groupby(['擅长位置''消费分段']).size().unstack(fill_value=0)            fig_position_spend = px.bar(position_analysis.reset_index().melt(id_vars=['擅长位置'],                                                                              var_name='消费级别',                                                                              value_name='人数'),                                         x='擅长位置', y='人数', color='消费级别',                                         title='不同位置偏好的消费分布',                                         barmode='stack',                                         color_discrete_map={'低消费''#95a5a6', '中消费''#f39c12', '高消费''#e74c3c'})            st.plotly_chart(fig_position_spend, use_container_width=True)        else:            st.warning("消费分段字段不存在,无法进行偏好分群分析")    # 5. 按行为分群    with st.expander("🎭 按行为分群", expanded=True):        col1, col2 = st.columns(2)        with col1:            behavior_rank = df.groupby(['行为模式''游戏段位']).size().unstack(fill_value=0)            fig_behavior_rank = px.bar(behavior_rank.reset_index().melt(id_vars=['行为模式'],                                                                         var_name='段位',                                                                         value_name='人数'),                                      x='行为模式', y='人数', color='段位',                                      title='不同行为模式的段位分布',                                      barmode='stack')            st.plotly_chart(fig_behavior_rank, use_container_width=True)        with col2:            # 确保df_processed中有消费分段字段            if '消费分段' in df_processed.columns:                # 创建一个包含行为模式和消费分段的DataFrame用于分组                temp_df = df_processed[['行为模式''消费分段']].copy()                behavior_spend = temp_df.groupby(['行为模式''消费分段']).size().unstack(fill_value=0)                fig_behavior_spend = px.bar(behavior_spend.reset_index().melt(id_vars=['行为模式'],                                                                               var_name='消费级别',                                                                               value_name='人数'),                                           x='行为模式', y='人数', color='消费级别',                                           title='不同行为模式的消费分布',                                           barmode='stack',                                           color_discrete_map={'低消费''#95a5a6', '中消费''#f39c12', '高消费''#e74c3c'})                st.plotly_chart(fig_behavior_spend, use_container_width=True)            else:                st.warning("消费分段字段不存在,无法进行行为模式的消费分布分析")# 关联与相关性分析def correlation_analysis(df, df_processed):    st.markdown("## 🔗 关联与相关性分析")    # 1. 消费驱动因素    with st.expander("💰 消费驱动因素分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            # 创建一个包含所需字段的DataFrame用于散点图            scatter_df = df_processed[['日均时长''累计消费']].copy()            if '消费分段' in df_processed.columns:                scatter_df['消费分段'] = df_processed['消费分段']                fig_spend_duration = px.scatter(scatter_df, x='日均时长', y='累计消费',                                               title='日均时长 vs 累计消费',                                               color='消费分段',                                               labels={'日均时长''日均时长(小时)''累计消费''累计消费(元)'})            else:                fig_spend_duration = px.scatter(scatter_df, x='日均时长', y='累计消费',                                               title='日均时长 vs 累计消费',                                               labels={'日均时长''日均时长(小时)''累计消费''累计消费(元)'})            st.plotly_chart(fig_spend_duration, use_container_width=True)        with col2:            fig_spend_rank = px.box(df, x='游戏段位', y='累计消费',                                   title='不同段位的消费分布',                                   labels={'游戏段位''段位''累计消费''累计消费(元)'})            fig_spend_rank.update_xaxes(tickangle=45)            st.plotly_chart(fig_spend_rank, use_container_width=True)        with col1:            fig_spend_winrate = px.scatter(df, x='综合胜率', y='累计消费',                                          title='综合胜率 vs 累计消费',                                          labels={'综合胜率''胜率''累计消费''累计消费(元)'})            st.plotly_chart(fig_spend_winrate, use_container_width=True)    # 2. 活跃度影响因素    with st.expander("📊 活跃度影响因素分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            login_age = df.groupby(['玩家年龄''登录频率']).size().unstack(fill_value=0)            login_age.columns.name = '登录频率'            fig_login_age = px.imshow(login_age.values,                                     x=login_age.columns,                                     y=login_age.index,                                     title='年龄 vs 登录频率热力图',                                     labels=dict(x="登录频率", y="年龄", color="人数"),                                     aspect="auto")            st.plotly_chart(fig_login_age, use_container_width=True)        with col2:            login_region = df.groupby(['所在区域''登录频率']).size().unstack(fill_value=0)            login_region.columns.name = '登录频率'            fig_login_region = px.imshow(login_region.values,                                        x=login_region.columns,                                        y=login_region.index,                                        title='区域 vs 登录频率热力图',                                        labels=dict(x="登录频率", y="区域", color="人数"))            st.plotly_chart(fig_login_region, use_container_width=True)    # 3. 技能成长路径    with st.expander("📈 技能成长路径分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            fig_kda_duration = px.scatter(df, x='日均时长', y='KDA指数',                                        title='日均时长 vs KDA指数',                                        color='游戏段位',                                        labels={'日均时长''日均时长(小时)''KDA指数''KDA指数'})            st.plotly_chart(fig_kda_duration, use_container_width=True)        with col2:            fig_kda_rank = px.box(df, x='游戏段位', y='KDA指数',                                title='不同段位的KDA分布',                                labels={'游戏段位''段位''KDA指数''KDA指数'})            fig_kda_rank.update_xaxes(tickangle=45)            st.plotly_chart(fig_kda_rank, use_container_width=True)    # 4. 区域差异分析    with st.expander("🗺️ 区域差异分析", expanded=True):        col1, col2, col3 = st.columns(3)        with col1:            region_spend = df.groupby('所在区域')['累计消费'].mean().sort_values(ascending=False)            fig_region_spend = px.bar(x=region_spend.index, y=region_spend.values,                                     title='各区域平均消费',                                     labels={'x''区域''y''平均消费(元)'},                                     color=region_spend.values,                                     color_continuous_scale='Plasma')            st.plotly_chart(fig_region_spend, use_container_width=True)        with col2:            region_active = df_processed.groupby('所在区域')['日均时长'].mean().sort_values(ascending=False)            fig_region_active = px.bar(x=region_active.index, y=region_active.values,                                      title='各区域平均日均时长',                                      labels={'x''区域''y''平均时长(小时)'},                                      color=region_active.values,                                      color_continuous_scale='Blues')            st.plotly_chart(fig_region_active, use_container_width=True)        with col3:            # 段位分布            region_rank = pd.crosstab(df['所在区域'], df['游戏段位'])            fig_region_rank = px.imshow(region_rank.values,                                       x=region_rank.columns,                                       y=region_rank.index,                                       title='区域 vs 段位分布热力图',                                       labels=dict(x="段位", y="区域", color="人数"))            st.plotly_chart(fig_region_rank, use_container_width=True)# 预测性分析def predictive_analysis(df, df_processed):    st.markdown("## 🔮 预测性分析")    # 1. 用户流失预测    with st.expander("⚠️ 用户流失预测", expanded=True):        df_processed['流失风险'] = df_processed.apply(predict_churn_risk, axis=1)        df_processed['流失风险等级'] = pd.cut(df_processed['流失风险'],                                              bins=[0123],                                              labels=['低风险''中风险''高风险'])        col1, col2 = st.columns(2)        with col1:            churn_dist = df_processed['流失风险等级'].value_counts()            fig_churn = px.pie(churn_dist, values=churn_dist.values, names=churn_dist.index,                              title='流失风险分布', hole=0.5,                              color_discrete_sequence=['#2ecc71', '#f39c12', '#e74c3c'])            st.plotly_chart(fig_churn, use_container_width=True)        with col2:            # 确保使用df_processed中包含消费分段字段的数据            if '消费分段' in df_processed.columns:                # 创建一个包含登录频率和消费分段的DataFrame用于分组                temp_df = df_processed[['登录频率''消费分段']].copy()                churn_login = temp_df.groupby(['登录频率''消费分段']).size().reset_index(name='人数')                fig_churn_login = px.bar(churn_login, x='登录频率', y='人数', color='消费分段',                                        title='登录频率与消费关系',                                        barmode='stack')                st.plotly_chart(fig_churn_login, use_container_width=True)            else:                # 如果消费分段不存在,使用游戏段位                temp_df = df_processed[['登录频率''游戏段位']].copy()                churn_login = temp_df.groupby(['登录频率''游戏段位']).size().reset_index(name='人数')                fig_churn_login = px.bar(churn_login, x='登录频率', y='人数', color='游戏段位',                                        title='登录频率与段位关系',                                        barmode='stack')                st.plotly_chart(fig_churn_login, use_container_width=True)        # 流失用户详细分析        st.markdown("### 高流失风险用户特征")        high_churn = df_processed[df_processed['流失风险等级'] == '高风险']        if len(high_churn) > 0:            col1, col2, col3, col4 = st.columns(4)            with col1:                st.metric("高风险人数", len(high_churn))            with col2:                st.metric("平均日均时长", f"{high_churn['日均时长'].mean():.1f}h")            with col3:                st.metric("平均累计消费", f"¥{high_churn['累计消费'].mean():.1f}")            with col4:                st.metric("平均胜率", f"{high_churn['综合胜率'].mean()*100:.1f}%")    # 2. 付费潜力预测    with st.expander("💎 付费潜力预测", expanded=True):        df_processed['付费潜力'] = df_processed.apply(predict_pay_potential, axis=1)        col1, col2 = st.columns(2)        with col1:            potential_dist = df_processed['付费潜力'].value_counts()            fig_potential = px.pie(potential_dist, values=potential_dist.values, names=potential_dist.index,                                  title='付费潜力分布', hole=0.5,                                  color_discrete_sequence=['#3498db', '#f39c12', '#e74c3c'])            st.plotly_chart(fig_potential, use_container_width=True)        with col2:            potential_rank = df_processed.groupby(['付费潜力''游戏段位']).size().reset_index(name='人数')            fig_potential_rank = px.bar(potential_rank, x='游戏段位', y='人数', color='付费潜力',                                       title='不同段位的付费潜力分布',                                       barmode='stack')            fig_potential_rank.update_xaxes(tickangle=45)            st.plotly_chart(fig_potential_rank, use_container_width=True)    # 3. 段位晋升预测    with st.expander("🏆 段位晋升预测", expanded=True):        df_processed['预计晋升时间'] = df_processed.apply(predict_promotion_time, axis=1)        col1, col2 = st.columns(2)        with col1:            promotion_dist = df_processed['预计晋升时间'].value_counts()            fig_promotion = px.bar(promotion_dist, x=promotion_dist.index, y=promotion_dist.values,                                  title='段位晋升时间预测分布',                                  labels={'x''预计晋升时间''y''人数'},                                  color=promotion_dist.values,                                  color_continuous_scale='RdYlGn_r')            st.plotly_chart(fig_promotion, use_container_width=True)        with col2:            promotion_kda = df_processed[df_processed['预计晋升时间'] != '已达巅峰'].groupby(                ['预计晋升时间''游戏段位']).size().reset_index(name='人数')            if len(promotion_kda) > 0:                fig_promotion_rank = px.bar(promotion_kda, x='游戏段位', y='人数', color='预计晋升时间',                                           title='不同段位的晋升时间预测',                                           barmode='stack')                fig_promotion_rank.update_xaxes(tickangle=45)                st.plotly_chart(fig_promotion_rank, use_container_width=True)# 运营决策支持def decision_support(df, df_processed):    st.markdown("## 📋 运营决策支持")    # 1. 高价值用户识别    with st.expander("💎 高价值用户识别", expanded=True):        df_processed['用户价值分'] = (            (df_processed['累计消费'] / df_processed['累计消费'].max()) * 100 * 0.5 +            df_processed['活跃度分数'] / df_processed['活跃度分数'].max() * 50 * 0.3 +            df_processed['技能分数'] / df_processed['技能分数'].max() * 20 * 0.2        )        top_users = df_processed.nlargest(10'用户价值分')        st.markdown("### TOP 10 高价值用户")        user_display = top_users[['用户ID''游戏段位''累计消费''日均时长''综合胜率''KDA指数''登录频率']].copy()        user_display['综合胜率'] = (user_display['综合胜率'] * 100).round(1).astype(str) + '%'        st.dataframe(user_display, use_container_width=True)        st.markdown("### 📌 运营建议")        st.info("""        **针对高价值用户的专属福利策略:**        - 发放专属限量皮肤/道具        - 提供优先客服通道        - 邀请参与内测和赛事        - 定期推送个性化内容推荐        - 设置VIP专属活动日        """)    # 2. 流失预警干预    with st.expander("⚠️ 流失预警干预", expanded=True):        # 如果流失风险等级字段不存在,先创建它        if '流失风险等级' not in df_processed.columns:            df_processed['流失风险'] = df_processed.apply(predict_churn_risk, axis=1)            df_processed['流失风险等级'] = pd.cut(df_processed['流失风险'],                                                  bins=[0123],                                                  labels=['低风险''中风险''高风险'])        high_churn = df_processed[df_processed['流失风险等级'] == '高风险'].nlargest(10'累计消费')        if len(high_churn) > 0:            st.markdown("### 需要重点召回的高价值流失风险用户")            churn_display = high_churn[['用户ID''游戏段位''累计消费''日均时长''登录频率''行为模式']].copy()            st.dataframe(churn_display, use_container_width=True)        else:            st.info("未发现高风险流失用户")        st.markdown("### 📌 召回策略")        st.warning("""        **对登录频率下降用户的召回活动:**        - 发送回归礼包和专属福利        - 推送好友互动提醒        - 邀请参与回归专属活动        - 根据行为模式推送个性化内容        - 设置连续登录奖励        """)    # 3. 匹配优化建议    with st.expander("⚔️ 匹配优化建议", expanded=True):        # 段位KDA统计        rank_stats = df.groupby('游戏段位').agg({            '综合胜率''mean',            'KDA指数''mean',            '日均时长''mean'        }).round(3)        st.markdown("### 各段位平均数据")        st.dataframe(rank_stats, use_container_width=True)        st.markdown("### 📌 匹配建议")        st.success("""        **根据段位、胜率、KDA优化对战匹配算法:**        - 扩大匹配考虑维度:综合胜率 + KDA指数 + 日均时长        - 设置动态匹配范围:活跃时间短的玩家匹配更接近水平的对手        - 引入段位保护机制:连续败北时适当降低匹配难度        - 组队匹配优化:综合计算队伍平均实力        - 避免新手对老手:根据注册时间和游戏时长增加匹配权重        """)    # 4. 内容推荐    with st.expander("🎯 内容推荐", expanded=True):        col1, col2 = st.columns(2)        with col1:            st.markdown("#### 按位置偏好推荐")            position_rec = df.groupby('擅长位置').agg({                '累计消费''mean',                '日均时长''mean',                '综合胜率''mean'            }).round(2)            st.dataframe(position_rec, use_container_width=True)        with col2:            st.markdown("#### 按行为模式推荐")            behavior_rec = df.groupby('行为模式').agg({                '累计消费''mean',                '日均时长''mean',                '玩家年龄''mean'            }).round(2)            st.dataframe(behavior_rec, use_container_width=True)        st.markdown("### 📌 推荐策略")        st.info("""        **根据擅长位置和行为模式推荐游戏内容:**        **竞技型玩家:**        - 推荐排位赛活动和赛事        - 新英雄/技能攻略        - 高段位对局回放        **社交型玩家:**        - 推荐组队开黑活动        - 好友系统功能        - 公会/战队内容        **休闲型玩家:**        - 推荐娱乐模式活动        - 皮肤和外观内容        - 成就任务系统        **收藏型玩家:**        - 推荐限定皮肤和道具        - 收集成就系统        - 稀有道具活动        """)    # 5. 定价策略    with st.expander("💰 定价策略", expanded=True):        region_pricing = df.groupby('所在区域').agg({            '累计消费': ['mean''median''std']        }).round(2)        region_pricing.columns = ['平均消费''中位数消费''消费标准差']        fig_region_pricing = px.bar(region_pricing, x=region_pricing.index, y='平均消费',                                   title='各区域平均消费对比',                                   labels={'x''区域''平均消费''平均消费(元)'},                                   color='平均消费',                                   color_continuous_scale='Viridis')        st.plotly_chart(fig_region_pricing, use_container_width=True)        st.dataframe(region_pricing, use_container_width=True)        st.markdown("### 📌 定价建议")        st.info("""        **基于区域消费差异制定差异化定价:**        - **高消费区域**:可推出更多高价值礼包,提供会员专属服务        - **中等消费区域**:平衡定价策略,推出性价比优惠组合        - **低消费区域**:增加小额多次消费选项,降低单次消费门槛        - **区域性促销**:针对不同区域节日和特点推出活动        - **分层定价**:同一产品提供基础版、进阶版、豪华版        """)# 可视化分析def visualization_analysis(df, df_processed):    st.markdown("## 📊 可视化分析")    # 1. 用户分布    with st.expander("🗺️ 用户分布分析", expanded=True):        tab1, tab2 = st.tabs(["区域热力图""年龄/段位金字塔"])        with tab1:            # 区域分布热力            region_age = pd.crosstab(df['所在区域'], df_processed['年龄分段'])            fig_region_heat = px.imshow(region_age.values,                                       x=region_age.columns,                                       y=region_age.index,                                       title='区域 × 年龄分布热力图',                                       labels=dict(x="年龄段", y="区域", color="人数"),                                       color_continuous_scale='YlOrRd',                                       aspect="auto")            st.plotly_chart(fig_region_heat, use_container_width=True)        with tab2:            # 年龄段位金字塔            rank_order = ['荣耀青铜''秩序白银''尊贵铂金''永恒钻石''至尊星耀''最强王者']            age_order = ['青少年''青年''成年''中老年']            pyramid_data = []            for age in age_order:                for rank in rank_order:                    count = len(df_processed[(df_processed['年龄分段'] == age) & (df_processed['游戏段位'] == rank)])                    pyramid_data.append({'年龄段': age, '段位': rank, '人数': count})            pyramid_df = pd.DataFrame(pyramid_data)            fig_pyramid = px.bar(pyramid_df, x='人数', y='段位',                               color='年龄段',                               orientation='h',                               title='年龄×段位分布金字塔',                               labels={'人数''人数''段位''段位'},                               barmode='stack',                               color_discrete_map={'青少年''#3498db', '青年''#2ecc71',                                                   '成年''#f39c12', '中老年''#e74c3c'})            st.plotly_chart(fig_pyramid, use_container_width=True)    # 2. 趋势分析    with st.expander("📈 趋势分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            login_order = ['每月几次''每周1-2次''每周3-5次''每天']            login_freq = df['登录频率'].value_counts().reindex(login_order)            fig_login_trend = px.line(x=login_freq.index, y=login_freq.values,                                     title='登录频率趋势',                                     labels={'x''登录频率''y''人数'},                                     markers=True)            fig_login_trend.update_traces(line_color='#3498db', marker_size=10)            st.plotly_chart(fig_login_trend, use_container_width=True)        with col2:            # 日均时长分段            df_processed['时长分段'] = pd.cut(df_processed['日均时长'],                                             bins=[0246, float('inf')],                                             labels=['0-2小时''2-4小时''4-6小时''6+小时'])            duration_dist = df_processed['时长分段'].value_counts()            fig_duration_trend = px.bar(x=duration_dist.index, y=duration_dist.values,                                       title='日均时长分布',                                       labels={'x''时长分段''y''人数'},                                       color=duration_dist.values,                                       color_continuous_scale='Blues')            st.plotly_chart(fig_duration_trend, use_container_width=True)    # 3. 对比分析    with st.expander("📊 对比分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            gender_spend = df.groupby('玩家性别')['累计消费'].mean().reset_index()            fig_gender_spend = px.bar(gender_spend, x='玩家性别', y='累计消费',                                      title='性别消费对比',                                      labels={'玩家性别''性别''累计消费''平均消费(元)'},                                      color='累计消费',                                      color_continuous_scale='RdYlGn')            st.plotly_chart(fig_gender_spend, use_container_width=True)        with col2:            region_active = df_processed.groupby('所在区域')['日均时长'].mean().sort_values(ascending=False).reset_index()            fig_region_active = px.bar(region_active, x='所在区域', y='日均时长',                                       title='区域活跃度对比',                                       labels={'所在区域''区域''日均时长''平均日均时长(小时)'},                                       color='日均时长',                                       color_continuous_scale='YlOrRd')            st.plotly_chart(fig_region_active, use_container_width=True)        # 性别段位对比        col1, col2 = st.columns(2)        with col1:            gender_rank = pd.crosstab(df['玩家性别'], df['游戏段位'])            fig_gender_rank = px.imshow(gender_rank.values,                                       x=gender_rank.columns,                                       y=gender_rank.index,                                       title='性别 × 段位分布热力图',                                       labels=dict(x="段位", y="性别", color="人数"),                                       color_continuous_scale='Viridis',                                       aspect="auto")            st.plotly_chart(fig_gender_rank, use_container_width=True)        with col2:            gender_kda = df.groupby('玩家性别')[['KDA指数''综合胜率']].mean()            gender_kda['综合胜率'] = gender_kda['综合胜率'] * 100            fig_gender_kda = px.bar(gender_kda.reset_index().melt(id_vars=['玩家性别']),                                   x='玩家性别', y='value', color='variable',                                   title='性别 × 技能指标对比',                                   labels={'玩家性别''性别''value''数值''variable''指标'},                                   barmode='group')            st.plotly_chart(fig_gender_kda, use_container_width=True)    # 4. 关联分析(散点图)    with st.expander("🔗 关联分析", expanded=True):        col1, col2 = st.columns(2)        with col1:            fig_scatter1 = px.scatter(df, x='日均时长', y='累计消费',                                     title='日均时长 vs 累计消费',                                     labels={'日均时长''日均时长(小时)''累计消费''累计消费(元)'},                                     color='游戏段位',                                     opacity=0.6)            st.plotly_chart(fig_scatter1, use_container_width=True)        with col2:            fig_scatter2 = px.scatter(df, x='综合胜率', y='KDA指数',                                     title='综合胜率 vs KDA指数',                                     labels={'综合胜率''胜率''KDA指数''KDA指数'},                                     color='游戏段位',                                     opacity=0.6)            st.plotly_chart(fig_scatter2, use_container_width=True)        # 3D散点图        fig_3d = px.scatter_3d(df, x='日均时长', y='累计消费', z='综合胜率',                              color='游戏段位',                              title='多维度关联分析(3D)',                              labels={'日均时长''日均时长''累计消费''累计消费''综合胜率''胜率'},                              opacity=0.7)        st.plotly_chart(fig_3d, use_container_width=True)    # 5. 分群分析(雷达图)    with st.expander("🎯 分群分析 - 用户画像雷达图", expanded=True):        col1, col2 = st.columns(2)        with col1:            # 按行为模式分群            behavior_radar = df.groupby('行为模式').agg({                '玩家年龄''mean',                '日均时长''mean',                '累计消费''mean',                '综合胜率''mean',                'KDA指数''mean'            }).reset_index()            behavior_radar['综合胜率'] = behavior_radar['综合胜率'] * 100            fig_radar1 = px.line_polar(behavior_radar, r='综合胜率', theta='行为模式',                                      line_close=True, title='各行为模式胜率对比')            st.plotly_chart(fig_radar1, use_container_width=True)        with col2:            # 按段位分群            rank_radar = df.groupby('游戏段位').agg({                '日均时长''mean',                '累计消费''mean',                '综合胜率''mean',                'KDA指数''mean'            }).reset_index()            rank_radar['综合胜率'] = rank_radar['综合胜率'] * 100            # 标准化数据用于雷达图            radar_data = rank_radar.melt(id_vars=['游戏段位'], var_name='指标', value_name='数值')            for col in ['日均时长''累计消费''综合胜率''KDA指数']:                max_val = radar_data[radar_data['指标'] == col]['数值'].max()                radar_data.loc[radar_data['指标'] == col, '数值'] = radar_data.loc[                    radar_data['指标'] == col, '数值'] / max_val * 100            fig_radar2 = px.line_polar(radar_data[radar_data['游戏段位'] == '最强王者'],                                      r='数值', theta='指标',                                      line_close=True, title='最强王者玩家画像')            st.plotly_chart(fig_radar2, use_container_width=True)        # 多行为模式对比雷达图        st.markdown("### 各行为模式综合画像对比")        fig_radar_compare = go.Figure()        categories = ['年龄''日均时长''累计消费''胜率''KDA']        for behavior in ['竞技型''社交型''休闲型''娱乐型''收藏型']:            if behavior in behavior_radar['行为模式'].values:                data = behavior_radar[behavior_radar['行为模式'] == behavior].iloc[0]                values = [                    (data['玩家年龄'] / behavior_radar['玩家年龄'].max()) * 100,                    (data['日均时长'] / behavior_radar['日均时长'].max()) * 100,                    (data['累计消费'] / behavior_radar['累计消费'].max()) * 100,                    data['综合胜率'],                    (data['KDA指数'] / behavior_radar['KDA指数'].max()) * 100                ]                fig_radar_compare.add_trace(go.Scatterpolar(                    r=values,                    theta=categories,                    fill='toself',                    name=behavior                ))        fig_radar_compare.update_layout(            polar=dict(radialaxis=dict(visible=True, range=[0100])),            showlegend=True,            title="各行为模式综合画像对比(标准化后)"        )        st.plotly_chart(fig_radar_compare, use_container_width=True)# 主函数def main():    # 标题    st.markdown('<div class="main-header">🎮 游戏玩家数据分析平台</div>', unsafe_allow_html=True)    # 侧边栏    with st.sidebar:        st.header("📂 数据上传")        # 文件上传        uploaded_file = st.file_uploader("上传CSV文件", type=['csv'])        if uploaded_file:            st.success(f"✅ 已加载: {uploaded_file.name}")        else:            st.info("💡 请上传包含玩家数据的CSV文件")            st.markdown("""            **数据格式要求:**            - 用户ID            - 玩家性别            - 玩家年龄            - 所在区域            - 游戏段位            - 日均时长            - 累计消费            - 擅长位置            - 综合胜率            - KDA指数            - 登录频率            - 行为模式            """)        # 默认使用示例数据        if uploaded_file is None:            try:                import os                default_file = r"d:\daku\游戏玩家数据分析\player_behavior_data.csv"                if os.path.exists(default_file):                    uploaded_file = open(default_file, 'rb', encoding=None)                    st.info(f"使用默认数据: {os.path.basename(default_file)}")            except:                pass    # 数据加载    if uploaded_file:        df = load_data(uploaded_file)        df_processed = preprocess_data(df)        # 显示关键指标        metrics = calculate_metrics(df)        st.markdown("---")        col1, col2, col3, col4, col5, col6, col7 = st.columns(7)        with col1:            st.metric("👥 总玩家数", metrics['总玩家数'])        with col2:            st.metric("🎂 平均年龄", f"{metrics['平均年龄']}岁")        with col3:            st.metric("⏱️ 平均日均时长", f"{metrics['平均日均时长']}h")        with col4:            st.metric("💰 总累计消费", f"¥{metrics['总累计消费']:,.0f}")        with col5:            st.metric("💵 平均消费", f"¥{metrics['平均累计消费']:.1f}")        with col6:            st.metric("🏆 平均胜率", f"{metrics['平均胜率']}%")        with col7:            st.metric("⚔️ 平均KDA", metrics['平均KDA'])        st.markdown("---")        # 分析模块选择        analysis_type = st.radio(            "📊 选择分析模块",            ["📈 用户画像分析""🎯 用户细分/分群分析""🔗 关联与相关性分析",             "🔮 预测性分析""📋 运营决策支持""📊 可视化分析"],            horizontal=True,            label_visibility="collapsed"        )        # 执行对应分析        if analysis_type == "📈 用户画像分析":            user_profile_analysis(df, df_processed)        elif analysis_type == "🎯 用户细分/分群分析":            segmentation_analysis(df, df_processed)        elif analysis_type == "🔗 关联与相关性分析":            correlation_analysis(df, df_processed)        elif analysis_type == "🔮 预测性分析":            predictive_analysis(df, df_processed)        elif analysis_type == "📋 运营决策支持":            decision_support(df, df_processed)        elif analysis_type == "📊 可视化分析":            visualization_analysis(df, df_processed)    else:        # 欢迎页面        st.markdown("""        <div style="text-align: center; padding: 40px 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; color: white; margin-bottom: 40px;">            <h1 style="font-size: 3.5rem; margin-bottom: 20px;">🎮 游戏玩家数据分析平台</h1>            <p style="font-size: 1.5rem; margin-bottom: 30px;">基于Python与Streamlit构建的多维度数据分析应用</p>            <div style="background: rgba(255,255,255,0.2); padding: 20px; border-radius: 15px; display: inline-block;">                <p style="font-size: 1.2rem; margin: 0;">📁 请在左侧上传CSV文件开始分析</p>            </div>        </div>        """, unsafe_allow_html=True)        # 平台特色介绍        st.markdown('<div class="section-header">🌟 平台特色</div>', unsafe_allow_html=True)        col1, col2, col3, col4 = st.columns(4)        with col1:            st.markdown("""            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">                <div class="feature-icon">📊</div>                <div class="feature-title">多维度分析</div>                <div class="feature-description">                    基于12个玩家维度的全面分析,涵盖人口统计、游戏能力、行为习惯和消费能力                </div>            </div>            """, unsafe_allow_html=True)        with col2:            st.markdown("""            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">                <div class="feature-icon">🎯</div>                <div class="feature-title">智能分群</div>                <div class="feature-description">                    支持5种用户细分方式:价值、活跃度、技能、偏好、行为模式分群                </div>            </div>            """, unsafe_allow_html=True)        with col3:            st.markdown("""            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">                <div class="feature-icon">🔮</div>                <div class="feature-title">预测分析</div>                <div class="feature-description">                    提供流失预测、付费潜力预测、段位晋升预测等智能分析功能                </div>            </div>            """, unsafe_allow_html=True)        with col4:            st.markdown("""            <div style="text-align: center; padding: 25px; background: #f8f9fa; border-radius: 15px; height: 280px;">                <div class="feature-icon">💡</div>                <div class="feature-title">决策支持</div>                <div class="feature-description">                    基于数据分析结果,提供可执行的运营策略和决策建议                </div>            </div>            """, unsafe_allow_html=True)        # 功能介绍卡片        st.markdown('<div class="section-header">📋 功能模块</div>', unsafe_allow_html=True)        # 第一行功能        col1, col2, col3 = st.columns(3)        with col1:            with st.container():                st.markdown('<div class="info-card">', unsafe_allow_html=True)                st.markdown("### 📈 用户画像分析")                st.markdown("- 👥 **人口统计画像**: 性别、年龄、区域分布")                st.markdown("- ⚔️ **游戏能力画像**: 段位、胜率、KDA、位置")                st.markdown("- 🎯 **行为习惯画像**: 时长、登录频率、行为模式")                st.markdown("- 💰 **消费能力画像**: 消费分布、消费能力评估")                st.markdown('</div>', unsafe_allow_html=True)        with col2:            with st.container():                st.markdown('<div class="info-card">', unsafe_allow_html=True)                st.markdown("### 🎯 用户细分分析")                st.markdown("- 💎 **按价值分群**: 高/中/低消费用户")                st.markdown("- 🔥 **按活跃度分群**: 核心/普通/流失用户")                st.markdown("- 🎮 **按技能分群**: 新手/进阶/高手")                st.markdown("- ⭐ **按偏好分群**: 不同位置偏好")                st.markdown("- 🎭 **按行为分群**: 社交/竞技/休闲型")                st.markdown('</div>', unsafe_allow_html=True)        with col3:            with st.container():                st.markdown('<div class="info-card">', unsafe_allow_html=True)                st.markdown("### 🔗 关联性分析")                st.markdown("- 💰 **消费驱动因素**: 时长、段位、胜率与消费关系")                st.markdown("- 📊 **活跃度影响因素**: 年龄、区域对活跃度影响")                st.markdown("- 📈 **技能成长路径**: 时长、段位与KDA关联")                st.markdown("- 🗺️ **区域差异分析**: 各区域消费、段位、活跃度对比")                st.markdown('</div>', unsafe_allow_html=True)        # 第二行功能        col4, col5, col6 = st.columns(3)        with col4:            with st.container():                st.markdown('<div class="warning-card">', unsafe_allow_html=True)                st.markdown("### 🔮 预测性分析")                st.markdown("- ⚠️ **用户流失预测**: 基于登录频率、时长、行为模式")                st.markdown("- 💎 **付费潜力预测**: 基于段位、活跃度、行为模式")                st.markdown("- 🏆 **段位晋升预测**: 基于KDA、胜率、游戏时长")                st.markdown('</div>', unsafe_allow_html=True)        with col5:            with st.container():                st.markdown('<div class="success-card">', unsafe_allow_html=True)                st.markdown("### 📋 运营决策支持")                st.markdown("- 💎 **高价值用户识别**: TOP10用户及运营策略")                st.markdown("- ⚠️ **流失预警干预**: 需要召回的用户及策略")                st.markdown("- ⚔️ **匹配优化建议**: 优化对战匹配算法")                st.markdown("- 🎯 **内容推荐**: 基于位置偏好推荐")                st.markdown("- 💰 **定价策略**: 区域差异化定价")                st.markdown('</div>', unsafe_allow_html=True)        with col6:            with st.container():                st.markdown('<div class="info-card">', unsafe_allow_html=True)                st.markdown("### 📊 可视化分析")                st.markdown("- 🗺️ **用户分布**: 区域热力图、年龄/段位金字塔")                st.markdown("- 📈 **趋势分析**: 登录频率、日均时长趋势")                st.markdown("- 📊 **对比分析**: 性别消费、区域活跃度对比")                st.markdown("- 🔗 **关联分析**: 时长vs消费、胜率vs段位散点图")                st.markdown("- 🎯 **分群分析**: 用户画像雷达图")                st.markdown('</div>', unsafe_allow_html=True)        # 数据格式要求        st.markdown('<div class="section-header">📁 数据格式要求</div>', unsafe_allow_html=True)        data_format = """        <div style="background: #f8f9fapadding: 20px; border-radius: 15px; border-left: 5px solid #3498db;">        <h4>CSV文件需包含以下12个维度:</h4>        <table style="width: 100%; border-collapse: collapse; margin-top: 15px;">            <tr style="background: #3498dbcolor: white;">                <th style="padding: 12px; text-align: left;">字段</th>                <th style="padding: 12px; text-align: left;">说明</th>                <th style="padding: 12px; text-align: left;">示例</th>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">用户ID</td>                <td style="padding: 10px;">玩家唯一标识</td>                <td style="padding: 10px;">100001</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">玩家性别</td>                <td style="padding: 10px;">性别</td>                <td style="padding: 10px;">男/女</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">玩家年龄</td>                <td style="padding: 10px;">年龄</td>                <td style="padding: 10px;">27</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">所在区域</td>                <td style="padding: 10px;">区域</td>                <td style="padding: 10px;">华东/华南/华北</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">游戏段位</td>                <td style="padding: 10px;">段位</td>                <td style="padding: 10px;">荣耀青铜/尊贵铂金/最强王者</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">日均时长</td>                <td style="padding: 10px;">平均每日游戏时长(小时)</td>                <td style="padding: 10px;">3.9</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">累计消费</td>                <td style="padding: 10px;">累计消费金额(元)</td>                <td style="padding: 10px;">22.41</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">擅长位置</td>                <td style="padding: 10px;">擅长的游戏位置</td>                <td style="padding: 10px;">坦克/刺客/辅助/射手</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">综合胜率</td>                <td style="padding: 10px;">综合胜率(0-1之间)</td>                <td style="padding: 10px;">0.483</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">KDA指数</td>                <td style="padding: 10px;">KDA指数</td>                <td style="padding: 10px;">5.4</td>            </tr>            <tr style="border-bottom: 1px solid #ddd;">                <td style="padding: 10px;">登录频率</td>                <td style="padding: 10px;">登录频率</td>                <td style="padding: 10px;">每天/每周3-5次/每月几次</td>            </tr>            <tr>                <td style="padding: 10px;">行为模式</td>                <td style="padding: 10px;">行为模式类型</td>                <td style="padding: 10px;">竞技型/社交型/休闲型</td>            </tr>        </table>        </div>        """        st.markdown(data_format, unsafe_allow_html=True)if __name__ == "__main__":    main()

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-27 09:57:03 HTTP/2.0 GET : https://f.mffb.com.cn/a/483037.html
  2. 运行时间 : 0.239181s [ 吞吐率:4.18req/s ] 内存消耗:5,253.08kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=18e153aef4497e2d52c500d9ecd02bea
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000735s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001147s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000546s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000562s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001601s ]
  6. SELECT * FROM `set` [ RunTime:0.000513s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001278s ]
  8. SELECT * FROM `article` WHERE `id` = 483037 LIMIT 1 [ RunTime:0.001947s ]
  9. UPDATE `article` SET `lasttime` = 1774576623 WHERE `id` = 483037 [ RunTime:0.005780s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000665s ]
  11. SELECT * FROM `article` WHERE `id` < 483037 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001091s ]
  12. SELECT * FROM `article` WHERE `id` > 483037 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.007144s ]
  13. SELECT * FROM `article` WHERE `id` < 483037 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.010122s ]
  14. SELECT * FROM `article` WHERE `id` < 483037 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.017493s ]
  15. SELECT * FROM `article` WHERE `id` < 483037 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.018116s ]
0.242737s