当前位置:首页>python>一天一个Python知识点——Day 148:Pandas数据分析基础

一天一个Python知识点——Day 148:Pandas数据分析基础

  • 2026-02-05 01:02:26
一天一个Python知识点——Day 148:Pandas数据分析基础

一、Pandas生态系统全景

"""Pandas生态系统层次:1. 核心:Series(一维) + DataFrame(二维)2. 基础:NumPy数组作为底层存储3. 扩展:时间序列、分类数据、稀疏数据4. 集成:Matplotlib可视化、SQL/Excel/JSON读写5. 高级:GroupBy、窗口函数、数据透视表Pandas设计哲学:1. 表格化数据操作2. 自动对齐数据3. 处理缺失数据4. 灵活的数据重塑5. 强大的时间序列支持"""import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom datetime import datetime, timedeltaimport warningswarnings.filterwarnings('ignore')# 设置显示选项pd.set_option('display.max_rows'100)pd.set_option('display.max_columns'50)pd.set_option('display.width'150)pd.set_option('display.float_format''{:.2f}'.format)print(f"Pandas版本: {pd.__version__}")print(f"NumPy版本: {np.__version__}")# 检查Pandas配置print(f"\nPandas配置:")for key in ['display.max_rows''display.max_columns''display.width']:    print(f"  {key}{pd.get_option(key)}")

二、Pandas核心数据结构

1. Series:带标签的一维数组

def demonstrate_series():    """演示Series数据结构"""    print("=" * 80)    print("Pandas Series 数据结构")    print("=" * 80)    # 1. 多种创建方式    print("\n1. Series创建方式:")    # 从列表创建    s1 = pd.Series([1020304050])    print(f"从列表创建: {s1}")    # 从列表创建,指定索引    s2 = pd.Series([1020304050],                    index=['A''B''C''D''E'])    print(f"\n指定索引创建:\n{s2}")    # 从字典创建    s3 = pd.Series({'Alice'85'Bob'92'Charlie'78'David'88})    print(f"\n从字典创建:\n{s3}")    # 从NumPy数组创建    s4 = pd.Series(np.random.randn(5),                    index=pd.date_range('2024-01-01', periods=5))    print(f"\n从NumPy数组创建 (带日期索引):\n{s4}")    # 2. Series属性    print("\n2. Series属性:")    print(f"值: {s2.values}")    print(f"索引: {s2.index}")    print(f"数据类型: {s2.dtype}")    print(f"形状: {s2.shape}")    print(f"大小: {s2.size}")    print(f"是否为空: {s2.empty}")    print(f"维度: {s2.ndim}")    # 3. Series索引    print("\n3. Series索引:")    print(f"s2['B']: {s2['B']}")    print(f"s2[['A', 'C', 'E']]:\n{s2[['A''C''E']]}")    print(f"s2[1:4]:\n{s2[1:4]}")    print(f"s2[s2 > 30]:\n{s2[s2 > 30]}")    # 4. Series操作    print("\n4. Series操作:")    # 向量化运算    s5 = s2 * 2 + 10    print(f"向量化运算 (s2 * 2 + 10):\n{s5}")    # 统计运算    print(f"\n统计信息:")    print(f"  总和: {s2.sum()}")    print(f"  均值: {s2.mean():.2f}")    print(f"  标准差: {s2.std():.2f}")    print(f"  最小值: {s2.min()}")    print(f"  最大值: {s2.max()}")    print(f"  中位数: {s2.median()}")    print(f"  分位数: {s2.quantile([0.250.50.75])}")    # 5. Series方法    print("\n5. Series方法:")    # 排序    print(f"排序 (升序):\n{s2.sort_values()}")    print(f"排序 (降序):\n{s2.sort_values(ascending=False)}")    # 排名    print(f"排名:\n{s2.rank()}")    # 值计数    s6 = pd.Series(['A''B''A''C''B''A''D'])    print(f"\n值计数:\n{s6.value_counts()}")    # 唯一值    print(f"唯一值: {s6.unique()}")    print(f"值计数 (归一化):\n{s6.value_counts(normalize=True)}")    # 6. 处理缺失值    print("\n6. 缺失值处理:")    s7 = pd.Series([12, np.nan, 4, np.nan, 6])    print(f"原始Series: {s7}")    print(f"是否有缺失值: {s7.hasnans}")    print(f"缺失值数量: {s7.isna().sum()}")    print(f"非缺失值数量: {s7.notna().sum()}")    # 填充缺失值    s7_filled = s7.fillna(s7.mean())    print(f"均值填充后: {s7_filled}")    # 删除缺失值    s7_dropped = s7.dropna()    print(f"删除缺失值后: {s7_dropped}")    # 7. 索引操作    print("\n7. 索引操作:")    # 重命名索引    s8 = s2.rename({'A''Alpha''B''Beta'})    print(f"重命名索引:\n{s8}")    # 重置索引    s9 = s2.reset_index()    print(f"重置索引 (返回DataFrame):\n{s9}")    # 设置新索引    s10 = s2.set_axis(['X''Y''Z''W''V'])    print(f"设置新索引:\n{s10}")    # 8. 类型转换    print("\n8. 类型转换:")    s11 = pd.Series(['1''2''3''4''5'])    print(f"原始类型: {s11.dtype}")    s11_numeric = pd.to_numeric(s11)    print(f"转换后类型: {s11_numeric.dtype}")    print(f"转换后值: {s11_numeric}")    # 9. 时间序列Series    print("\n9. 时间序列Series:")    dates = pd.date_range('2024-01-01', periods=10, freq='D')    ts = pd.Series(np.random.randn(10), index=dates)    print(f"时间序列:\n{ts}")    print(f"索引类型: {type(ts.index)}")    print(f"日期范围: {ts.index.min()} 到 {ts.index.max()}")    # 时间序列操作    print(f"按月份重采样 (取均值):\n{ts.resample('M').mean()}")    return {        's1': s1, 's2': s2, 's3': s3, 's4': s4,        's6': s6, 's7': s7, 'ts': ts    }# 执行Series演示series_data = demonstrate_series()

2. DataFrame:带标签的二维表格

def demonstrate_dataframe():    """演示DataFrame数据结构"""    print("=" * 80)    print("Pandas DataFrame 数据结构")    print("=" * 80)    # 1. DataFrame创建    print("\n1. DataFrame创建方式:")    # 从字典创建    df1 = pd.DataFrame({        '姓名': ['张三''李四''王五''赵六'],        '年龄': [25303528],        '城市': ['北京''上海''广州''深圳'],        '薪资': [15000180002200016000]    })    print(f"从字典创建:\n{df1}")    # 从列表创建    data = [        ['苹果'5.510],        ['香蕉'3.220],        ['橙子'4.815],        ['葡萄'6.58]    ]    df2 = pd.DataFrame(data, columns=['水果''价格''库存'])    print(f"\n从列表创建:\n{df2}")    # 从NumPy数组创建    arr = np.random.randn(54)    df3 = pd.DataFrame(arr,                        columns=['A''B''C''D'],                       index=pd.date_range('2024-01-01', periods=5))    print(f"\n从NumPy数组创建:\n{df3}")    # 从Series创建    df4 = pd.DataFrame({        '成绩': pd.Series([85927888], index=['A''B''C''D']),        '等级': pd.Series(['A''A''B''B'], index=['A''B''C''D'])    })    print(f"\n从Series创建:\n{df4}")    # 2. DataFrame属性    print("\n2. DataFrame属性:")    print(f"形状: {df1.shape}")    print(f"维度: {df1.ndim}")    print(f"大小: {df1.size}")    print(f"列名: {df1.columns.tolist()}")    print(f"索引: {df1.index.tolist()}")    print(f"数据类型:\n{df1.dtypes}")    print(f"内存使用: {df1.memory_usage().sum()} bytes")    # 3. 数据查看    print("\n3. 数据查看方法:")    print(f"前2行:\n{df1.head(2)}")    print(f"后2行:\n{df1.tail(2)}")    print(f"随机3行:\n{df1.sample(3, random_state=42)}")    print(f"基本信息:\n{df1.info()}")    print(f"描述性统计:\n{df1.describe()}")    print(f"详细描述 (包含所有列):\n{df1.describe(include='all')}")    # 4. 数据选择    print("\n4. 数据选择:")    # 选择列    print(f"选择单列 (df1['姓名']):\n{df1['姓名']}")    print(f"选择多列 (df1[['姓名', '薪资']]):\n{df1[['姓名''薪资']]}")    # 选择行    print(f"\n选择单行 (df1.iloc[1]):\n{df1.iloc[1]}")    print(f"选择多行 (df1.iloc[1:3]):\n{df1.iloc[1:3]}")    # loc索引器    print(f"\nloc选择 (df1.loc[1:2, ['姓名', '年龄']]):\n{df1.loc[1:2, ['姓名''年龄']]}")    # iloc索引器    print(f"iloc选择 (df1.iloc[0:2, 0:2]):\n{df1.iloc[0:20:2]}")    # 条件选择    print(f"\n条件选择 (df1[df1['薪资'] > 17000]):\n{df1[df1['薪资'] > 17000]}")    print(f"多条件选择 (df1[(df1['年龄'] > 28) & (df1['薪资'] > 16000)]):")    print(df1[(df1['年龄'] > 28) & (df1['薪资'] > 16000)])    # 5. 数据操作    print("\n5. 数据操作:")    # 添加新列    df1['薪资等级'] = np.where(df1['薪资'] > 17000'高''中')    print(f"添加新列:\n{df1}")    # 修改列    df1['年龄加1'] = df1['年龄'] + 1    print(f"\n修改列:\n{df1}")    # 删除列    df1_dropped = df1.drop(columns=['年龄加1'])    print(f"删除列:\n{df1_dropped}")    # 重命名列    df1_renamed = df1.rename(columns={'姓名''Name''年龄''Age'})    print(f"重命名列:\n{df1_renamed}")    # 6. 数据处理    print("\n6. 数据处理:")    # 缺失值处理    df5 = pd.DataFrame({        'A': [12, np.nan, 4],        'B': [5, np.nan, np.nan, 8],        'C': [9101112]    })    print(f"原始数据:\n{df5}")    print(f"缺失值统计:\n{df5.isna().sum()}")    print(f"填充缺失值 (向前填充):\n{df5.fillna(method='ffill')}")    print(f"填充缺失值 (列均值):\n{df5.fillna(df5.mean())}")    # 重复值处理    df6 = pd.DataFrame({        '姓名': ['张三''李四''张三''王五''李四'],        '成绩': [8592857892]    })    print(f"\n重复数据:\n{df6}")    print(f"重复行:\n{df6[df6.duplicated()]}")    print(f"删除重复行:\n{df6.drop_duplicates()}")    print(f"删除重复行 (基于姓名):\n{df6.drop_duplicates(subset=['姓名'])}")    # 7. 数据转换    print("\n7. 数据转换:")    # 数据类型转换    print(f"数据类型:\n{df1.dtypes}")    df1['年龄'] = df1['年龄'].astype('float32')    print(f"转换后类型:\n{df1.dtypes}")    # 应用函数    df1['薪资千元'] = df1['薪资'].apply(lambda x: x/1000)    print(f"\n应用函数:\n{df1[['薪资''薪资千元']]}")    # 向量化操作    df1['薪资加10%'] = df1['薪资'] * 1.1    print(f"向量化操作:\n{df1[['薪资''薪资加10%']]}")    # 8. 数据排序    print("\n8. 数据排序:")    print(f"按薪资排序:\n{df1.sort_values('薪资')}")    print(f"按薪资降序排序:\n{df1.sort_values('薪资', ascending=False)}")    print(f"多列排序 (先按城市,再按薪资):")    print(df1.sort_values(['城市''薪资'], ascending=[TrueFalse]))    # 9. 数据分组    print("\n9. 数据分组:")    # 简单分组    grouped = df1.groupby('城市')    print(f"分组对象: {type(grouped)}")    # 分组聚合    print(f"按城市分组统计:\n{grouped.agg({'薪资': ['mean''sum''count'], '年龄''mean'})}")    # 分组转换    df1['城市平均薪资'] = grouped['薪资'].transform('mean')    print(f"添加城市平均薪资:\n{df1}")    # 10. 数据透视表    print("\n10. 数据透视表:")    # 创建示例数据    sales_data = pd.DataFrame({        '日期': pd.date_range('2024-01-01', periods=30).tolist() * 3,        '产品': ['A'] * 30 + ['B'] * 30 + ['C'] * 30,        '类别': np.random.choice(['电子产品''日用品''服装'], 90),        '销售额': np.random.randint(100100090),        '数量': np.random.randint(11090)    })    # 创建透视表    pivot = pd.pivot_table(sales_data,                          values='销售额',                          index='产品',                          columns='类别',                          aggfunc='sum',                          fill_value=0)    print(f"销售额透视表:\n{pivot}")    # 多级透视表    pivot_multi = pd.pivot_table(sales_data,                                values=['销售额''数量'],                                index=['产品''类别'],                                aggfunc={'销售额''sum''数量''mean'})    print(f"\n多级透视表:\n{pivot_multi}")    return {        'df1': df1, 'df2': df2, 'df3': df3, 'df4': df4,        'df5': df5, 'df6': df6, 'sales_data': sales_data,        'pivot': pivot, 'pivot_multi': pivot_multi    }# 执行DataFrame演示dataframes = demonstrate_dataframe()

三、数据导入与导出

def demonstrate_data_io():    """演示数据导入导出操作"""    print("=" * 80)    print("数据导入与导出")    print("=" * 80)    # 1. 创建示例数据    print("1. 创建示例数据")    # 员工数据    employees = pd.DataFrame({        '员工ID': ['E001''E002''E003''E004''E005'],        '姓名': ['张三''李四''王五''赵六''钱七'],        '部门': ['技术部''市场部''技术部''人事部''市场部'],        '入职日期': pd.date_range('2023-01-01', periods=5, freq='M'),        '薪资': [1500018000220001600019000],        '绩效评分': [8592788890]    })    # 销售数据    sales = pd.DataFrame({        '订单ID': ['O001''O002''O003''O004''O005'],        '员工ID': ['E001''E002''E001''E003''E004'],        '产品': ['电脑''手机''平板''电脑''手机'],        '数量': [21312],        '单价': [50003000200050003000],        '日期': pd.date_range('2024-01-01', periods=5, freq='D')    })    print(f"员工数据:\n{employees}")    print(f"\n销售数据:\n{sales}")    # 2. 导出数据    print("\n2. 导出数据到不同格式:")    # 导出到CSV    employees.to_csv('employees.csv', index=False, encoding='utf-8-sig')    sales.to_csv('sales.csv', index=False, encoding='utf-8-sig')    # 导出到Excel    with pd.ExcelWriter('company_data.xlsx'as writer:        employees.to_excel(writer, sheet_name='员工信息', index=False)        sales.to_excel(writer, sheet_name='销售记录', index=False)    # 导出到JSON    employees.to_json('employees.json', orient='records', force_ascii=False)    # 导出到Parquet(高效列式存储)    try:        employees.to_parquet('employees.parquet')        print("已导出到Parquet格式")    except ImportError:        print("安装pyarrow以支持Parquet格式: pip install pyarrow")    # 导出到SQL数据库    import sqlite3    # 创建内存数据库    conn = sqlite3.connect(':memory:')    employees.to_sql('employees', conn, if_exists='replace', index=False)    sales.to_sql('sales', conn, if_exists='replace', index=False)    print("\n已导出到SQLite数据库")    # 3. 导入数据    print("\n3. 从不同格式导入数据:")    # 从CSV导入    employees_csv = pd.read_csv('employees.csv', encoding='utf-8-sig')    print(f"从CSV导入:\n{employees_csv.head()}")    # 从Excel导入    employees_excel = pd.read_excel('company_data.xlsx', sheet_name='员工信息')    sales_excel = pd.read_excel('company_data.xlsx', sheet_name='销售记录')    print(f"\n从Excel导入员工数据:\n{employees_excel.head()}")    # 从JSON导入    employees_json = pd.read_json('employees.json')    print(f"\n从JSON导入:\n{employees_json.head()}")    # 从Parquet导入    try:        employees_parquet = pd.read_parquet('employees.parquet')        print(f"\n从Parquet导入:\n{employees_parquet.head()}")    except ImportError:        print("\n跳过Parquet导入测试")    # 从SQL导入    employees_sql = pd.read_sql('SELECT * FROM employees', conn)    sales_sql = pd.read_sql('SELECT * FROM sales', conn)    print(f"\n从SQL导入员工数据:\n{employees_sql.head()}")    # 4. 读取大型文件    print("\n4. 读取大型文件技巧:")    # 分块读取    chunk_size = 2    chunks = []    for chunk in pd.read_csv('employees.csv', chunksize=chunk_size, encoding='utf-8-sig'):        chunks.append(chunk)        print(f"读取块 {len(chunks)}:\n{chunk}")    # 合并块    if chunks:        large_df = pd.concat(chunks, ignore_index=True)        print(f"\n合并后的数据:\n{large_df}")    # 5. 数据预览    print("\n5. 数据预览方法:")    # 查看文件信息    import os    print(f"文件大小: {os.path.getsize('employees.csv')} bytes")    # 只读取前几行    preview = pd.read_csv('employees.csv', nrows=3, encoding='utf-8-sig')    print(f"预览前3行:\n{preview}")    # 6. 数据类型优化    print("\n6. 数据类型优化:")    # 查看内存使用    print(f"原始数据内存使用: {employees.memory_usage().sum()} bytes")    # 优化数据类型    employees_optimized = employees.copy()    # 转换整数类型    employees_optimized['员工ID'] = employees_optimized['员工ID'].astype('category')    employees_optimized['姓名'] = employees_optimized['姓名'].astype('category')    employees_optimized['部门'] = employees_optimized['部门'].astype('category')    # 转换数值类型    employees_optimized['薪资'] = employees_optimized['薪资'].astype('int32')    employees_optimized['绩效评分'] = employees_optimized['绩效评分'].astype('int8')    print(f"优化后内存使用: {employees_optimized.memory_usage().sum()} bytes")    print(f"内存节省: {(employees.memory_usage().sum() - employees_optimized.memory_usage().sum()) / employees.memory_usage().sum() * 100:.1f}%")    # 7. 清理临时文件    import os    for file in ['employees.csv''sales.csv''company_data.xlsx'                 'employees.json''employees.parquet']:        if os.path.exists(file):            os.remove(file)    print("\n已清理临时文件")    return {        'employees': employees,        'sales': sales,        'employees_optimized': employees_optimized,        'conn': conn    }# 执行数据IO演示io_data = demonstrate_data_io()

四、数据清洗与预处理

def demonstrate_data_cleaning():    """演示数据清洗与预处理"""    print("=" * 80)    print("数据清洗与预处理")    print("=" * 80)    # 1. 创建脏数据    print("1. 创建包含问题的数据集")    # 创建有问题的数据    dirty_data = pd.DataFrame({        '客户ID': ['C001''C002''C003''C004''C005''C001''C006''C007'None'C009'],        '姓名': ['Alice''Bob''Charlie''David''Eve''Alice''Frank''Grace''Henry''Ivy'],        '年龄': [25303528222545322931],        '城市': ['北京''上海''广州''深圳''北京''北京''上海''广州''深圳'None],        '消费金额': [1500.502800.001200.753500.25800.001500.504200.501900.001300.752600.00],        '消费日期': ['2024-01-15''2024-01-16''2024-01-16''2024-01-17'                   '2024-01-17''2024-01-15''2024-01-18''2024-01-18'                   '2024-01-19''2024-01-20'],        '会员等级': ['Gold''Silver''Bronze''Gold''Silver''Gold''Platinum'                    'Silver''Bronze''Gold'],        '联系电话': ['13800138000''13900139000''13700137000''13600136000'                   '13500135000''13800138000''13400134000''13300133000'                   '13200132000''13100131000']    })    # 添加更多问题    dirty_data.loc[2'年龄'] = 350  # 异常值    dirty_data.loc[4'消费金额'] = -800  # 负值    dirty_data.loc[7'年龄'] = None  # 缺失值    dirty_data.loc[9'会员等级'] = 'Diamond'  # 异常类别    print(f"原始数据 (包含各种问题):\n{dirty_data}")    # 2. 识别问题    print("\n2. 识别数据问题:")    # 缺失值分析    print("缺失值分析:")    missing_info = pd.DataFrame({        '缺失数量': dirty_data.isna().sum(),        '缺失比例': dirty_data.isna().sum() / len(dirty_data) * 100    })    print(missing_info)    # 重复值分析    print(f"\n重复行数量: {dirty_data.duplicated().sum()}")    print(f"重复行:\n{dirty_data[dirty_data.duplicated()]}")    # 异常值分析    print("\n异常值分析:")    numeric_cols = dirty_data.select_dtypes(include=[np.number]).columns    for col in numeric_cols:        Q1 = dirty_data[col].quantile(0.25)        Q3 = dirty_data[col].quantile(0.75)        IQR = Q3 - Q1        lower_bound = Q1 - 1.5 * IQR        upper_bound = Q3 + 1.5 * IQR        outliers = dirty_data[(dirty_data[col] < lower_bound) | (dirty_data[col] > upper_bound)]        print(f"{col}{len(outliers)} 个异常值")    # 3. 处理缺失值    print("\n3. 处理缺失值:")    cleaned_data = dirty_data.copy()    # 删除客户ID缺失的行    cleaned_data = cleaned_data.dropna(subset=['客户ID'])    print(f"删除客户ID缺失的行后: {len(cleaned_data)} 行")    # 填充城市缺失值    cleaned_data['城市'] = cleaned_data['城市'].fillna('未知')    print("城市缺失值已填充为'未知'")    # 4. 处理重复值    print("\n4. 处理重复值:")    # 删除完全重复的行    cleaned_data = cleaned_data.drop_duplicates()    print(f"删除完全重复行后: {len(cleaned_data)} 行")    # 5. 处理异常值    print("\n5. 处理异常值:")    # 处理年龄异常值 (350岁不合理)    age_median = cleaned_data['年龄'].median()    cleaned_data['年龄'] = cleaned_data['年龄'].apply(        lambda x: age_median if pd.notna(x) and x > 120 else x    )    print(f"年龄异常值已用中位数 ({age_median}) 替换")    # 处理消费金额负值    cleaned_data['消费金额'] = cleaned_data['消费金额'].abs()    print("消费金额负值已转换为正值")    # 6. 数据类型转换    print("\n6. 数据类型转换:")    # 转换消费日期为datetime    cleaned_data['消费日期'] = pd.to_datetime(cleaned_data['消费日期'])    print(f"消费日期已转换为datetime类型: {cleaned_data['消费日期'].dtype}")    # 转换会员等级为分类类型    valid_categories = ['Bronze''Silver''Gold''Platinum']    cleaned_data['会员等级'] = pd.Categorical(        cleaned_data['会员等级'],        categories=valid_categories,        ordered=True    )    print(f"会员等级已转换为分类类型: {cleaned_data['会员等级'].dtype}")    # 7. 特征工程    print("\n7. 特征工程:")    # 提取日期特征    cleaned_data['消费年份'] = cleaned_data['消费日期'].dt.year    cleaned_data['消费月份'] = cleaned_data['消费日期'].dt.month    cleaned_data['消费日'] = cleaned_data['消费日期'].dt.day    cleaned_data['消费星期'] = cleaned_data['消费日期'].dt.day_name()    # 创建客户年龄分段    bins = [0253550100]    labels = ['青年''中青年''中年''中老年']    cleaned_data['年龄分段'] = pd.cut(cleaned_data['年龄'], bins=bins, labels=labels)    # 创建消费金额分段    amount_bins = [01000200030005000]    amount_labels = ['低''中''高''很高']    cleaned_data['消费等级'] = pd.cut(cleaned_data['消费金额'], bins=amount_bins, labels=amount_labels)    # 8. 数据标准化/归一化    print("\n8. 数据标准化:")    from sklearn.preprocessing import StandardScaler, MinMaxScaler    # Z-score标准化    scaler_z = StandardScaler()    cleaned_data['消费金额_zscore'] = scaler_z.fit_transform(        cleaned_data[['消费金额']]    )    # Min-Max归一化    scaler_mm = MinMaxScaler()    cleaned_data['消费金额_minmax'] = scaler_mm.fit_transform(        cleaned_data[['消费金额']]    )    # 9. 处理分类变量    print("\n9. 处理分类变量:")    # One-Hot编码    city_dummies = pd.get_dummies(cleaned_data['城市'], prefix='城市')    print(f"城市One-Hot编码:\n{city_dummies.head()}")    # 标签编码    from sklearn.preprocessing import LabelEncoder    le = LabelEncoder()    cleaned_data['会员等级编码'] = le.fit_transform(cleaned_data['会员等级'])    print(f"会员等级标签编码: {dict(zip(le.classes_, le.transform(le.classes_)))}")    # 10. 数据验证    print("\n10. 数据验证:")    print("清洗后数据信息:")    print(cleaned_data.info())    print("\n清洗后数据描述性统计:")    print(cleaned_data.describe(include='all'))    print("\n清洗后缺失值统计:")    print(cleaned_data.isna().sum())    print("\n清洗后重复行统计:")    print(cleaned_data.duplicated().sum())    # 可视化清洗效果    fig, axes = plt.subplots(22, figsize=(1210))    # 1. 缺失值对比    axes[00].bar(missing_info.index, missing_info['缺失比例'])    axes[00].set_title('原始数据缺失值比例')    axes[00].set_ylabel('缺失比例 (%)')    axes[00].tick_params(axis='x', rotation=45)    # 2. 年龄分布对比    axes[01].hist(dirty_data['年龄'].dropna(), bins=10, alpha=0.5, label='原始', color='red')    axes[01].hist(cleaned_data['年龄'].dropna(), bins=10, alpha=0.5, label='清洗后', color='blue')    axes[01].set_title('年龄分布对比')    axes[01].set_xlabel('年龄')    axes[01].set_ylabel('频数')    axes[01].legend()    # 3. 消费金额箱线图对比    amount_data = [dirty_data['消费金额'].dropna(), cleaned_data['消费金额']]    axes[10].boxplot(amount_data, labels=['原始''清洗后'])    axes[10].set_title('消费金额分布对比')    axes[10].set_ylabel('消费金额')    # 4. 会员等级分布    member_counts = cleaned_data['会员等级'].value_counts().sort_index()    axes[11].bar(member_counts.index.astype(str), member_counts.values)    axes[11].set_title('清洗后会员等级分布')    axes[11].set_xlabel('会员等级')    axes[11].set_ylabel('客户数')    plt.suptitle('数据清洗效果可视化', fontsize=16, y=1.02)    plt.tight_layout()    plt.show()    return {        'dirty_data': dirty_data,        'cleaned_data': cleaned_data,        'city_dummies': city_dummies,        'missing_info': missing_info    }# 执行数据清洗演示cleaning_data = demonstrate_data_cleaning()

五、数据聚合与分析

def demonstrate_data_aggregation():    """演示数据聚合与分析"""    print("=" * 80)    print("数据聚合与分析")    print("=" * 80)    # 1. 创建销售数据集    print("1. 创建销售数据集")    np.random.seed(42)    n_records = 1000    dates = pd.date_range('2024-01-01', periods=90, freq='D')    products = ['手机''电脑''平板''耳机''手表']    regions = ['华东''华南''华北''华中''西南''西北']    categories = ['电子产品''配件']    sales_data = pd.DataFrame({        '订单ID': [f'ORD{i:05d}' for i in range(1, n_records + 1)],        '日期': np.random.choice(dates, n_records),        '产品': np.random.choice(products, n_records, p=[0.30.250.20.150.1]),        '类别': np.random.choice(categories, n_records, p=[0.70.3]),        '地区': np.random.choice(regions, n_records),        '销售员ID': [f'SAL{np.random.randint(121):03d}' for _ in range(n_records)],        '数量': np.random.randint(16, n_records),        '单价': np.random.choice([2999599919993991299], n_records),        '折扣': np.random.uniform(0.91.0, n_records)  # 9-10折    })    # 计算金额    sales_data['金额'] = sales_data['数量'] * sales_data['单价'] * sales_data['折扣']    # 添加客户评分    sales_data['评分'] = np.random.randint(16, n_records)    print(f"销售数据形状: {sales_data.shape}")    print(f"\n数据预览:\n{sales_data.head()}")    # 2. 基本聚合    print("\n2. 基本聚合计算:")    print(f"总销售额: {sales_data['金额'].sum():,.2f}")    print(f"平均销售额: {sales_data['金额'].mean():,.2f}")    print(f"总订单数: {sales_data['订单ID'].nunique()}")    print(f"平均订单金额: {sales_data['金额'].sum() / sales_data['订单ID'].nunique():,.2f}")    # 3. GroupBy聚合    print("\n3. GroupBy聚合:")    # 按地区分组    region_stats = sales_data.groupby('地区').agg({        '订单ID''count',        '金额': ['sum''mean''std'],        '评分''mean'    }).round(2)    region_stats.columns = ['订单数''总金额''平均金额''金额标准差''平均评分']    print(f"按地区统计:\n{region_stats}")    # 4. 多级分组    print("\n4. 多级分组:")    product_region_stats = sales_data.groupby(['产品''地区']).agg({        '订单ID''count',        '金额''sum',        '评分''mean'    }).round(2)    print(f"按产品和地区统计 (前10行):\n{product_region_stats.head(10)}")    # 5. 透视表    print("\n5. 透视表分析:")    # 销售额透视表    pivot_sales = pd.pivot_table(        sales_data,        values='金额',        index='产品',        columns='地区',        aggfunc='sum',        fill_value=0,        margins=True,  # 添加总计        margins_name='总计'    )    print(f"销售额透视表:\n{pivot_sales}")    # 多指标透视表    pivot_multi = pd.pivot_table(        sales_data,        values=['金额''数量''评分'],        index=['产品''类别'],        aggfunc={'金额''sum''数量''sum''评分''mean'}    ).round(2)    print(f"\n多指标透视表:\n{pivot_multi}")    # 6. 交叉表    print("\n6. 交叉表分析:")    # 产品和类别的交叉表    cross_tab = pd.crosstab(        sales_data['产品'],        sales_data['类别'],        margins=True,        margins_name='总计'    )    print(f"产品×类别交叉表:\n{cross_tab}")    # 带数值的交叉表    cross_tab_value = pd.crosstab(        sales_data['产品'],        sales_data['类别'],        values=sales_data['金额'],        aggfunc='sum',        margins=True,        margins_name='总计'    ).round(2)    print(f"\n产品×类别金额交叉表:\n{cross_tab_value}")    # 7. 时间序列聚合    print("\n7. 时间序列聚合:")    # 按日统计    daily_sales = sales_data.groupby(pd.Grouper(key='日期', freq='D')).agg({        '订单ID''count',        '金额''sum'    }).rename(columns={'订单ID''订单数''金额''日销售额'})    # 按周统计    weekly_sales = sales_data.groupby(pd.Grouper(key='日期', freq='W')).agg({        '订单ID''count',        '金额''sum'    }).rename(columns={'订单ID''订单数''金额''周销售额'})    # 按月统计    monthly_sales = sales_data.groupby(pd.Grouper(key='日期', freq='M')).agg({        '订单ID''count',        '金额''sum',        '评分''mean'    }).rename(columns={'订单ID''订单数''金额''月销售额''评分''平均评分'})    print(f"月度销售统计:\n{monthly_sales}")    # 8. 窗口函数    print("\n8. 窗口函数:")    # 创建时间序列示例    ts_data = daily_sales['日销售额'].copy()    # 移动平均    ts_data['MA_7'] = ts_data.rolling(window=7).mean()  # 7日移动平均    ts_data['MA_30'] = ts_data.rolling(window=30).mean()  # 30日移动平均    # 扩展窗口统计    ts_data['累计销售额'] = ts_data.expanding().sum()    ts_data['历史最高'] = ts_data.expanding().max()    print(f"时间序列窗口统计 (前10行):\n{ts_data.head(10)}")    # 9. 排名和分位数    print("\n9. 排名和分位数:")    # 销售员排名    salesperson_stats = sales_data.groupby('销售员ID').agg({        '订单ID''count',        '金额''sum'    }).rename(columns={'订单ID''订单数''金额''总销售额'})    salesperson_stats['销售额排名'] = salesperson_stats['总销售额'].rank(ascending=False, method='min')    salesperson_stats['订单数排名'] = salesperson_stats['订单数'].rank(ascending=False, method='min')    # 分位数分析    salesperson_stats['销售额分位数'] = pd.qcut(        salesperson_stats['总销售额'],         q=4        labels=['低''中下''中上''高']    )    print(f"销售员排名分析:\n{salesperson_stats.sort_values('销售额排名').head()}")    # 10. 高级聚合技巧    print("\n10. 高级聚合技巧:")    # 自定义聚合函数    def iqr(x):        """计算四分位距"""        return x.quantile(0.75) - x.quantile(0.25)    def cv(x):        """计算变异系数"""        return x.std() / x.mean() if x.mean() != 0 else 0    # 应用自定义函数    advanced_stats = sales_data.groupby('产品').agg({        '金额': ['sum''mean''std', iqr, cv],        '数量': ['sum''mean'],        '评分': ['mean''std'lambda x: x.mode()[0if not x.mode().empty else np.nan]    }).round(2)    # 重命名列    advanced_stats.columns = [        '总金额''平均金额''金额标准差''金额IQR''金额CV',        '总数量''平均数量',        '平均评分''评分标准差''评分众数'    ]    print(f"高级统计:\n{advanced_stats}")    # 可视化分析结果    fig, axes = plt.subplots(22, figsize=(1510))    # 1. 地区销售额柱状图    region_stats['总金额'].plot(kind='bar', ax=axes[00], color='steelblue')    axes[00].set_title('各地区总销售额')    axes[00].set_xlabel('地区')    axes[00].set_ylabel('销售额')    axes[00].tick_params(axis='x', rotation=45)    # 2. 产品销售额堆叠柱状图    product_region_pivot = sales_data.pivot_table(        values='金额'        index='产品'        columns='地区'        aggfunc='sum'    )    product_region_pivot.plot(kind='bar', stacked=True, ax=axes[01])    axes[01].set_title('各产品在不同地区的销售额')    axes[01].set_xlabel('产品')    axes[01].set_ylabel('销售额')    axes[01].legend(title='地区', bbox_to_anchor=(1.051))    # 3. 时间序列图    axes[10].plot(daily_sales.index, daily_sales['日销售额'], label='日销售额', alpha=0.7)    axes[10].plot(weekly_sales.index, weekly_sales['周销售额'], label='周销售额', linewidth=2)    axes[10].set_title('销售额时间序列')    axes[10].set_xlabel('日期')    axes[10].set_ylabel('销售额')    axes[10].legend()    axes[10].grid(True, alpha=0.3)    # 4. 散点图:数量 vs 金额    axes[11].scatter(sales_data['数量'], sales_data['金额'], alpha=0.5)    axes[11].set_title('数量 vs 金额')    axes[11].set_xlabel('数量')    axes[11].set_ylabel('金额')    axes[11].grid(True, alpha=0.3)    plt.suptitle('销售数据分析可视化', fontsize=16, y=1.02)    plt.tight_layout()    plt.show()    return {        'sales_data': sales_data,        'region_stats': region_stats,        'daily_sales': daily_sales,        'weekly_sales': weekly_sales,        'monthly_sales': monthly_sales,        'salesperson_stats': salesperson_stats,        'advanced_stats': advanced_stats    }# 执行数据聚合演示aggregation_data = demonstrate_data_aggregation()

六、时间序列分析

def demonstrate_time_series():    """演示时间序列分析"""    print("=" * 80)    print("Pandas时间序列分析")    print("=" * 80)    # 1. 创建时间序列数据    print("1. 创建时间序列数据")    np.random.seed(42)    # 生成日期范围    date_range = pd.date_range('2023-01-01''2023-12-31', freq='D')    # 创建时间序列DataFrame    time_series_data = pd.DataFrame({        '日期': date_range,        '销售额': np.random.normal(100002000len(date_range)).cumsum() + 100000,        '访问量': np.random.poisson(1000len(date_range)),        '转化率': np.random.beta(52len(date_range)) * 10,  # 0-10%        '客单价': np.random.normal(50050len(date_range))    })    # 添加趋势和季节性    time_series_data['销售额'] = time_series_data['销售额'] * (        1 + 0.001 * np.arange(len(date_range)) +  # 趋势        0.1 * np.sin(2 * np.pi * np.arange(len(date_range)) / 365)  # 年季节性    )    # 添加周季节性    time_series_data['访问量'] = time_series_data['访问量'] * (        1 + 0.2 * np.sin(2 * np.pi * time_series_data['日期'].dt.dayofweek / 7)    )    # 设置日期为索引    time_series_data.set_index('日期', inplace=True)    print(f"时间序列数据形状: {time_series_data.shape}")    print(f"\n数据预览:\n{time_series_data.head()}")    # 2. 时间序列基础操作    print("\n2. 时间序列基础操作:")    # 时间索引属性    print(f"索引类型: {type(time_series_data.index)}")    print(f"时间范围: {time_series_data.index.min()} 到 {time_series_data.index.max()}")    print(f"时间跨度: {time_series_data.index.max() - time_series_data.index.min()}")    # 按时间选择数据    print(f"\n选择2023年1月数据:\n{time_series_data.loc['2023-01'].head()}")    print(f"\n选择2023年第一季度数据:\n{time_series_data.loc['2023-Q1'].head()}")    print(f"\n选择特定日期范围:\n{time_series_data.loc['2023-01-15':'2023-01-20']}")    # 3. 时间频率转换    print("\n3. 时间频率转换:")    # 按日统计    print("原始数据 (日频)")    # 按周重采样    weekly_data = time_series_data.resample('W').agg({        '销售额''sum',        '访问量''sum',        '转化率''mean',        '客单价''mean'    })    print(f"\n周度数据:\n{weekly_data.head()}")    # 按月重采样    monthly_data = time_series_data.resample('M').agg({        '销售额': ['sum''mean''std'],        '访问量': ['sum''mean'],        '转化率''mean',        '客单价''mean'    })    monthly_data.columns = ['销售额_总和''销售额_均值''销售额_标准差'                          '访问量_总和''访问量_均值''转化率_均值''客单价_均值']    print(f"\n月度数据:\n{monthly_data.head()}")    # 4. 时间序列分解    print("\n4. 时间序列分解:")    # 使用statsmodels进行分解    try:        from statsmodels.tsa.seasonal import seasonal_decompose        # 使用加法模型分解销售额        result = seasonal_decompose(            time_series_data['销售额'],             model='additive',            period=30  # 月度周期        )        print("时间序列分解完成 (加法模型)")        print(f"  趋势成分: {len(result.trend)} 个点")        print(f"  季节成分: {len(result.seasonal)} 个点")        print(f"  残差成分: {len(result.resid)} 个点")    except ImportError:        print("安装statsmodels以进行时间序列分解: pip install statsmodels")        result = None    # 5. 移动窗口统计    print("\n5. 移动窗口统计:")    # 移动平均    time_series_data['销售额_MA7'] = time_series_data['销售额'].rolling(window=7).mean()    time_series_data['销售额_MA30'] = time_series_data['销售额'].rolling(window=30).mean()    # 移动标准差    time_series_data['销售额_Std7'] = time_series_data['销售额'].rolling(window=7).std()    # 扩展窗口统计    time_series_data['销售额_累计'] = time_series_data['销售额'].expanding().sum()    time_series_data['销售额_历史最高'] = time_series_data['销售额'].expanding().max()    print(f"移动窗口统计 (前10行):\n{time_series_data[['销售额''销售额_MA7''销售额_MA30']].head(10)}")    # 6. 时间差计算    print("\n6. 时间差计算:")    # 计算日环比    time_series_data['销售额_日环比'] = time_series_data['销售额'].pct_change(periods=1)    # 计算周同比    time_series_data['销售额_周同比'] = time_series_data['销售额'].pct_change(periods=7)    # 计算月同比    time_series_data['销售额_月同比'] = time_series_data['销售额'].pct_change(periods=30)    print(f"变化率统计:\n{time_series_data[['销售额_日环比''销售额_周同比''销售额_月同比']].head(10)}")    # 7. 时间序列特征提取    print("\n7. 时间序列特征提取:")    # 提取日期特征    time_series_data['年份'] = time_series_data.index.year    time_series_data['月份'] = time_series_data.index.month    time_series_data['季度'] = time_series_data.index.quarter    time_series_data['星期'] = time_series_data.index.dayofweek    time_series_data['是否周末'] = time_series_data.index.dayofweek >= 5    time_series_data['是否月初'] = time_series_data.index.day <= 7    time_series_data['是否月末'] = time_series_data.index.day >= 23    # 提取滚动特征    for window in [371430]:        time_series_data[f'销售额_MA{window}'] = time_series_data['销售额'].rolling(window=window).mean()        time_series_data[f'销售额_Std{window}'] = time_series_data['销售额'].rolling(window=window).std()        time_series_data[f'销售额_Min{window}'] = time_series_data['销售额'].rolling(window=window).min()        time_series_data[f'销售额_Max{window}'] = time_series_data['销售额'].rolling(window=window).max()    print(f"特征提取后数据形状: {time_series_data.shape}")    print(f"特征列:\n{list(time_series_data.columns[:15])}...")    # 8. 时间序列预测    print("\n8. 时间序列预测 (简单方法):")    # 使用简单移动平均预测    def moving_average_forecast(series, window_size, forecast_horizon):        """移动平均预测"""        forecast = []        for i in range(forecast_horizon):            # 使用最近window_size个值的平均值作为预测            pred = series.iloc[-window_size:].mean()            forecast.append(pred)            # 在预测中更新series(这里简单复制最后一个值)            series = pd.concat([series, pd.Series([pred])])        return forecast    # 预测未来7天    sales_series = time_series_data['销售额'].copy()    forecast_days = 7    forecast = moving_average_forecast(sales_series, window_size=30, forecast_horizon=forecast_days)    # 创建预测日期    forecast_dates = pd.date_range(        start=time_series_data.index[-1] + pd.Timedelta(days=1),        periods=forecast_days,        freq='D'    )    print(f"未来{forecast_days}天销售额预测:")    for date, value in zip(forecast_dates, forecast):        print(f"  {date.date()}{value:,.2f}")    # 9. 时间序列可视化    print("\n9. 时间序列可视化:")    fig, axes = plt.subplots(32, figsize=(1512))    # 1. 原始时间序列    axes[00].plot(time_series_data.index, time_series_data['销售额'])    axes[00].set_title('销售额时间序列')    axes[00].set_xlabel('日期')    axes[00].set_ylabel('销售额')    axes[00].grid(True, alpha=0.3)    # 2. 移动平均    axes[01].plot(time_series_data.index, time_series_data['销售额'], alpha=0.5, label='原始')    axes[01].plot(time_series_data.index, time_series_data['销售额_MA7'], label='7日移动平均')    axes[01].plot(time_series_data.index, time_series_data['销售额_MA30'], label='30日移动平均')    axes[01].set_title('移动平均分析')    axes[01].set_xlabel('日期')    axes[01].set_ylabel('销售额')    axes[01].legend()    axes[01].grid(True, alpha=0.3)    # 3. 月度汇总    monthly_data['销售额_总和'].plot(kind='bar', ax=axes[10])    axes[10].set_title('月度销售额')    axes[10].set_xlabel('月份')    axes[10].set_ylabel('销售额')    axes[10].tick_params(axis='x', rotation=45)    # 4. 星期分析    weekday_avg = time_series_data.groupby('星期')['销售额'].mean()    weekday_avg.index = ['周一''周二''周三''周四''周五''周六''周日']    weekday_avg.plot(kind='bar', ax=axes[11])    axes[11].set_title('星期平均销售额')    axes[11].set_xlabel('星期')    axes[11].set_ylabel('平均销售额')    # 5. 时间序列分解    if result is not None:        axes[20].plot(result.trend)        axes[20].set_title('趋势成分')        axes[20].set_xlabel('日期')        axes[20].set_ylabel('趋势')        axes[20].grid(True, alpha=0.3)        axes[21].plot(result.seasonal[:90])  # 只显示前90天的季节性        axes[21].set_title('季节成分 (前90天)')        axes[21].set_xlabel('日期')        axes[21].set_ylabel('季节性')        axes[21].grid(True, alpha=0.3)    plt.suptitle('时间序列分析可视化', fontsize=16, y=1.02)    plt.tight_layout()    plt.show()    return {        'time_series_data': time_series_data,        'weekly_data': weekly_data,        'monthly_data': monthly_data,        'forecast': forecast,        'forecast_dates': forecast_dates,        'result': result    }# 执行时间序列演示time_series_data = demonstrate_time_series()

七、数据合并与连接

def demonstrate_data_merging():    """演示数据合并与连接操作"""    print("=" * 80)    print("数据合并与连接")    print("=" * 80)    # 1. 创建示例数据集    print("1. 创建示例数据集")    # 员工信息表    employees = pd.DataFrame({        '员工ID': ['E001''E002''E003''E004''E005'],        '姓名': ['张三''李四''王五''赵六''钱七'],        '部门': ['技术部''市场部''技术部''人事部''市场部'],        '入职日期': pd.to_datetime(['2020-01-15''2019-03-20''2021-07-10''2018-11-05''2022-02-28'])    })    # 工资表    salaries = pd.DataFrame({        '员工ID': ['E001''E002''E003''E004''E006'],  # E005缺失,E006多余        '基本工资': [80009000850095007800],        '绩效奖金': [20003000250028002200],        '月份''2024-01'    })    # 部门信息表    departments = pd.DataFrame({        '部门': ['技术部''市场部''人事部''财务部'],        '部门经理': ['王经理''李经理''赵经理''钱经理'],        '预算': [1000000800000500000600000]    })    # 项目分配表    projects = pd.DataFrame({        '员工ID': ['E001''E001''E002''E003''E004''E004'],        '项目名称': ['项目A''项目B''项目A''项目C''项目B''项目D'],        '参与时长': [120801509010060]  # 小时    })    print(f"员工信息表:\n{employees}")    print(f"\n工资表:\n{salaries}")    print(f"\n部门信息表:\n{departments}")    print(f"\n项目分配表:\n{projects}")    # 2. 合并(Merge)操作    print("\n2. 合并(Merge)操作:")    # 内连接(默认)    inner_merge = pd.merge(employees, salaries, on='员工ID', how='inner')    print(f"内连接 (只保留两边都有的员工):\n{inner_merge}")    # 左连接    left_merge = pd.merge(employees, salaries, on='员工ID', how='left')    print(f"\n左连接 (保留所有员工,工资缺失的为NaN):\n{left_merge}")    # 右连接    right_merge = pd.merge(employees, salaries, on='员工ID', how='right')    print(f"\n右连接 (保留所有工资记录,员工信息缺失的为NaN):\n{right_merge}")    # 外连接    outer_merge = pd.merge(employees, salaries, on='员工ID', how='outer')    print(f"\n外连接 (保留所有记录):\n{outer_merge}")    # 3. 多对多合并    print("\n3. 多对多合并:")    # 员工和项目是多对多关系    employee_projects = pd.merge(employees, projects, on='员工ID', how='left')    print(f"员工项目分配:\n{employee_projects}")    # 4. 多键合并    print("\n4. 多键合并:")    # 创建包含年份的工资表    salaries_multi = pd.DataFrame({        '员工ID': ['E001''E001''E002''E002''E003'],        '年份': [20232024202320242024],        '工资': [1500016000180001900022000]    })    # 员工年份信息    employee_years = pd.DataFrame({        '员工ID': ['E001''E001''E002''E002''E003'],        '年份': [20232024202320242024],        '绩效评级': ['A''B''B''A''A']    })    multi_key_merge = pd.merge(salaries_multi, employee_years, on=['员工ID''年份'])    print(f"多键合并:\n{multi_key_merge}")    # 5. 连接(Join)操作    print("\n5. 连接(Join)操作:")    # 设置索引后连接    employees_idx = employees.set_index('员工ID')    salaries_idx = salaries.set_index('员工ID')    # 使用join方法    join_result = employees_idx.join(salaries_idx, how='left')    print(f"索引连接:\n{join_result}")    # 6. 拼接(Concat)操作    print("\n6. 拼接(Concat)操作:")    # 垂直拼接(添加行)    quarter1 = pd.DataFrame({        '产品': ['A''B''C'],        'Q1销售额': [100015001200]    })    quarter2 = pd.DataFrame({        '产品': ['A''B''C'],        'Q2销售额': [110016001300]    })    quarter3 = pd.DataFrame({        '产品': ['A''B''D'],  # 注意产品D不在前两个季度        'Q3销售额': [12001700900]    })    # 简单拼接    vertical_concat = pd.concat([quarter1, quarter2, quarter3], ignore_index=True)    print(f"垂直拼接:\n{vertical_concat}")    # 水平拼接(添加列)    horizontal_concat = pd.concat([quarter1, quarter2, quarter3], axis=1)    print(f"\n水平拼接:\n{horizontal_concat}")    # 更好的水平拼接方式    sales_data = quarter1.merge(quarter2, on='产品', how='outer')    sales_data = sales_data.merge(quarter3, on='产品', how='outer')    print(f"\n使用merge进行水平拼接:\n{sales_data}")    # 7. 追加(Append)操作    print("\n7. 追加(Append)操作:")    # 创建新员工    new_employee = pd.DataFrame({        '员工ID': ['E006'],        '姓名': ['孙八'],        '部门': ['财务部'],        '入职日期': [pd.Timestamp('2023-05-15')]    })    # 追加到员工表    employees_appended = employees.append(new_employee, ignore_index=True)    print(f"追加新员工:\n{employees_appended}")    # 8. 合并冲突处理    print("\n8. 合并冲突处理:")    # 创建有重叠列的DataFrame    df1 = pd.DataFrame({        'ID': [123],        '值': ['A''B''C'],        '共同列': [102030]    })    df2 = pd.DataFrame({        'ID': [234],        '值': ['B2''C2''D2'],        '共同列': [200300400]  # 与df1的'共同列'冲突    })    # 合并时有冲突列    merge_conflict = pd.merge(df1, df2, on='ID', suffixes=('_df1''_df2'))    print(f"冲突列处理 (使用后缀):\n{merge_conflict}")    # 9. 复杂合并:链式合并    print("\n9. 链式合并:")    # 合并多个表    # 先合并员工和工资    merged_step1 = pd.merge(employees, salaries, on='员工ID', how='left')    # 再合并部门信息    merged_step2 = pd.merge(merged_step1, departments, on='部门', how='left')    # 最后合并项目信息(需要聚合)    project_hours = projects.groupby('员工ID')['参与时长'].sum().reset_index()    final_merged = pd.merge(merged_step2, project_hours, on='员工ID', how='left')    # 计算总工资    final_merged['总工资'] = final_merged['基本工资'] + final_merged['绩效奖金']    final_merged['参与时长'] = final_merged['参与时长'].fillna(0)    print(f"链式合并结果:\n{final_merged}")    # 10. 性能优化技巧    print("\n10. 性能优化技巧:")    # 创建大型数据集    np.random.seed(42)    n_rows = 100000    large_df1 = pd.DataFrame({        'ID'range(n_rows),        '值1': np.random.randn(n_rows),        '键': np.random.choice(['A''B''C''D''E'], n_rows)    })    large_df2 = pd.DataFrame({        'ID'range(n_rows // 2, n_rows + n_rows // 2),        '值2': np.random.randn(n_rows),        '键': np.random.choice(['A''B''C''D''E'], n_rows)    })    # 测试不同合并方法的性能    import time    methods = ['merge''join''concat']    times = {}    for method in methods:        start = time.time()        if method == 'merge':            result = pd.merge(large_df1, large_df2, on='键', how='inner')        elif method == 'join':            df1_idx = large_df1.set_index('键')            df2_idx = large_df2.set_index('键')            result = df1_idx.join(df2_idx, how='inner', lsuffix='_df1', rsuffix='_df2')        else:  # concat            result = pd.concat([large_df1, large_df2], axis=1)        elapsed = time.time() - start        times[method] = elapsed        print(f"{method}{elapsed:.3f}秒, 结果形状: {result.shape}")    # 可视化合并性能    fig, ax = plt.subplots(figsize=(106))    bars = ax.bar(times.keys(), times.values())    ax.set_title('不同合并方法性能比较 (10万行数据)')    ax.set_ylabel('时间 (秒)')    ax.set_xlabel('合并方法')    # 添加数值标签    for bar in bars:        height = bar.get_height()        ax.text(bar.get_x() + bar.get_width()/2., height + 0.01,               f'{height:.3f}', ha='center', va='bottom')    plt.tight_layout()    plt.show()    return {        'employees': employees,        'salaries': salaries,        'departments': departments,        'projects': projects,        'inner_merge': inner_merge,        'final_merged': final_merged,        'merge_performance': times    }# 执行数据合并演示merge_data = demonstrate_data_merging()

八、实际案例分析:电商数据分析

def ecommerce_case_study():    """电商数据分析实战案例"""    print("=" * 80)    print("实战案例:电商数据分析")    print("=" * 80)    # 1. 数据准备    print("1. 数据准备")    np.random.seed(42)    n_customers = 1000    n_products = 50    n_transactions = 5000    # 生成客户数据    customers = pd.DataFrame({        '客户ID': [f'CUST{i:04d}' for i in range(1, n_customers + 1)],        '注册日期': pd.to_datetime(np.random.choice(            pd.date_range('2022-01-01''2024-01-01', freq='D'),            n_customers        )),        '城市': np.random.choice(['北京''上海''广州''深圳''杭州''成都''武汉''南京'],                               n_customers, p=[0.150.150.10.10.10.10.10.1]),        '年龄': np.random.randint(1860, n_customers),        '性别': np.random.choice(['男''女'], n_customers, p=[0.550.45]),        '会员等级': np.random.choice(['普通''白银''黄金''铂金'], n_customers,                                  p=[0.40.30.20.1])    })    # 生成产品数据    categories = ['电子产品''服装''家居''美妆''食品''图书']    products = pd.DataFrame({        '产品ID': [f'PROD{i:03d}' for i in range(1, n_products + 1)],        '产品名称': [f'产品{i}' for i in range(1, n_products + 1)],        '类别': np.random.choice(categories, n_products),        '子类别': np.random.choice(['手机''电脑''上衣''裤子''家具''餐具'                                 '护肤品''化妆品''零食''饮料''小说''教材'], n_products),        '成本价': np.round(np.random.uniform(50500, n_products), 2),        '售价': np.round(np.random.uniform(1001000, n_products), 2),        '库存': np.random.randint(0100, n_products)    })    # 计算利润率    products['利润率'] = (products['售价'] - products['成本价']) / products['售价']    # 生成交易数据    transactions = pd.DataFrame({        '订单ID': [f'ORDER{i:05d}' for i in range(1, n_transactions + 1)],        '客户ID': np.random.choice(customers['客户ID'], n_transactions),        '产品ID': np.random.choice(products['产品ID'], n_transactions),        '购买日期': pd.to_datetime(np.random.choice(            pd.date_range('2023-01-01''2024-01-01', freq='D'),            n_transactions        )),        '数量': np.random.randint(15, n_transactions),        '折扣': np.random.choice([1.00.950.90.85], n_transactions, p=[0.50.30.150.05])    })    print(f"客户数据: {customers.shape}")    print(f"产品数据: {products.shape}")    print(f"交易数据: {transactions.shape}")    # 2. 数据合并    print("\n2. 数据合并")    # 合并交易和产品数据    merged_data = pd.merge(transactions, products, on='产品ID', how='left')    # 合并客户数据    merged_data = pd.merge(merged_data, customers, on='客户ID', how='left')    # 计算交易金额    merged_data['交易金额'] = merged_data['数量'] * merged_data['售价'] * merged_data['折扣']    merged_data['成本'] = merged_data['数量'] * merged_data['成本价']    merged_data['利润'] = merged_data['交易金额'] - merged_data['成本']    print(f"合并后数据形状: {merged_data.shape}")    # 3. 数据分析    print("\n3. 数据分析")    # 3.1 总体销售情况    total_sales = merged_data['交易金额'].sum()    total_profit = merged_data['利润'].sum()    total_transactions = merged_data['订单ID'].nunique()    total_customers = merged_data['客户ID'].nunique()    print("总体销售情况:")    print(f"  总销售额: ¥{total_sales:,.2f}")    print(f"  总利润: ¥{total_profit:,.2f}")    print(f"  总订单数: {total_transactions}")    print(f"  总客户数: {total_customers}")    print(f"  客单价: ¥{total_sales/total_transactions:,.2f}")    print(f"  利润率: {total_profit/total_sales:.2%}")    # 3.2 月度销售趋势    monthly_sales = merged_data.groupby(pd.Grouper(key='购买日期', freq='M')).agg({        '订单ID''nunique',        '交易金额''sum',        '利润''sum',        '客户ID''nunique'    }).rename(columns={        '订单ID''订单数',        '交易金额''销售额',        '客户ID''客户数'    })    monthly_sales['客单价'] = monthly_sales['销售额'] / monthly_sales['订单数']    monthly_sales['利润率'] = monthly_sales['利润'] / monthly_sales['销售额']    print(f"\n月度销售趋势:\n{monthly_sales.round(2)}")    # 3.3 产品分析    product_analysis = merged_data.groupby(['产品ID''产品名称''类别']).agg({        '订单ID''count',        '交易金额''sum',        '利润''sum',        '数量''sum'    }).rename(columns={        '订单ID''销量',        '交易金额''销售额',        '数量''总销量'    })    product_analysis['利润率'] = product_analysis['利润'] / product_analysis['销售额']    product_analysis = product_analysis.sort_values('销售额', ascending=False)    print(f"\n热销产品Top 10:\n{product_analysis.head(10).round(2)}")    # 3.4 客户分析    customer_analysis = merged_data.groupby('客户ID').agg({        '订单ID''nunique',        '交易金额''sum',        '利润''sum',        '购买日期': ['min''max''count']    })    # 扁平化列名    customer_analysis.columns = ['订单数''总消费''总利润''首次购买''最后购买''购买次数']    # 计算RFM指标    reference_date = merged_data['购买日期'].max() + pd.Timedelta(days=1)    customer_analysis['最近消费天数'] = (reference_date - customer_analysis['最后购买']).dt.days    customer_analysis['购买频率'] = customer_analysis['购买次数'] / customer_analysis['订单数']    customer_analysis['平均订单价值'] = customer_analysis['总消费'] / customer_analysis['订单数']    print(f"\n高价值客户Top 10:\n{customer_analysis.sort_values('总消费', ascending=False).head(10).round(2)}")    # 3.5 地理分析    city_analysis = merged_data.groupby('城市').agg({        '客户ID''nunique',        '订单ID''nunique',        '交易金额''sum',        '利润''sum'    }).rename(columns={        '客户ID''客户数',        '订单ID''订单数',        '交易金额''销售额'    })    city_analysis['客单价'] = city_analysis['销售额'] / city_analysis['订单数']    city_analysis = city_analysis.sort_values('销售额', ascending=False)    print(f"\n城市销售分析:\n{city_analysis.round(2)}")    # 3.6 用户分群    print("\n4. 用户分群 (RFM分析)")    # RFM分箱    customer_analysis['R_Score'] = pd.qcut(customer_analysis['最近消费天数'], q=4, labels=[4321])    customer_analysis['F_Score'] = pd.qcut(customer_analysis['购买频率'], q=4, labels=[1234])    customer_analysis['M_Score'] = pd.qcut(customer_analysis['平均订单价值'], q=4, labels=[1234])    # 计算RFM总分    customer_analysis['RFM_Score'] = (        customer_analysis['R_Score'].astype(str) +         customer_analysis['F_Score'].astype(str) +         customer_analysis['M_Score'].astype(str)    )    # RFM分群    def rfm_segment(row):        if row['R_Score'] >= 3 and row['F_Score'] >= 3 and row['M_Score'] >= 3:            return '高价值客户'        elif row['R_Score'] >= 2 and row['F_Score'] >= 2:            return '潜力客户'        elif row['R_Score'] >= 2:            return '新客户'        elif row['F_Score'] >= 2:            return '忠诚客户'        else:            return '流失客户'    customer_analysis['客户分群'] = customer_analysis.apply(rfm_segment, axis=1)    segment_stats = customer_analysis.groupby('客户分群').agg({        '客户ID''count',        '总消费''sum',        '平均订单价值''mean'    }).rename(columns={'客户ID''客户数'})    print(f"客户分群结果:\n{segment_stats.round(2)}")    # 4. 可视化分析    print("\n5. 可视化分析")    fig, axes = plt.subplots(23, figsize=(1812))    # 1. 月度销售趋势    axes[00].plot(monthly_sales.index, monthly_sales['销售额'], marker='o')    axes[00].set_title('月度销售额趋势')    axes[00].set_xlabel('月份')    axes[00].set_ylabel('销售额')    axes[00].grid(True, alpha=0.3)    axes[00].tick_params(axis='x', rotation=45)    # 2. 产品类别销售额    category_sales = merged_data.groupby('类别')['交易金额'].sum().sort_values()    axes[01].barh(category_sales.index, category_sales.values)    axes[01].set_title('各品类销售额')    axes[01].set_xlabel('销售额')    # 3. 城市销售分布    city_sales = city_analysis['销售额'].sort_values(ascending=False)    axes[02].bar(city_sales.index, city_sales.values)    axes[02].set_title('城市销售额分布')    axes[02].set_xlabel('城市')    axes[02].set_ylabel('销售额')    axes[02].tick_params(axis='x', rotation=45)    # 4. 客户分群分布    segment_counts = segment_stats['客户数']    axes[10].pie(segment_counts.values, labels=segment_counts.index, autopct='%1.1f%%')    axes[10].set_title('客户分群占比')    # 5. 热销产品Top 10    top_products = product_analysis.head(10)    axes[11].barh(top_products.index.get_level_values(1), top_products['销售额'])    axes[11].set_title('热销产品Top 10')    axes[11].set_xlabel('销售额')    # 6. RFM散点图    scatter_data = customer_analysis.sample(100, random_state=42)  # 抽样显示    colors = {'高价值客户''green''潜力客户''blue'              '新客户''orange''忠诚客户''purple''流失客户''red'}    for segment, color in colors.items():        segment_data = scatter_data[scatter_data['客户分群'] == segment]        axes[12].scatter(segment_data['最近消费天数'],                           segment_data['平均订单价值'],                          c=color, label=segment, alpha=0.6)    axes[12].set_title('RFM分析散点图')    axes[12].set_xlabel('最近消费天数 (Recency)')    axes[12].set_ylabel('平均订单价值 (Monetary)')    axes[12].legend()    axes[12].grid(True, alpha=0.3)    plt.suptitle('电商数据分析仪表板', fontsize=16, y=1.02)    plt.tight_layout()    plt.show()    # 5. 生成分析报告    print("\n6. 生成分析报告摘要")    report = f"""    ============================================    电商数据分析报告    ============================================    1. 总体表现:    - 总销售额: ¥{total_sales:,.2f}    - 总利润: ¥{total_profit:,.2f}    - 总订单数: {total_transactions}    - 总客户数: {total_customers}    - 客单价: ¥{total_sales/total_transactions:,.2f}    - 整体利润率: {total_profit/total_sales:.2%}    2. 月度趋势:    - 最高月销售额: ¥{monthly_sales['销售额'].max():,.2f} ({monthly_sales['销售额'].idxmax().strftime('%Y-%m')})    - 最低月销售额: ¥{monthly_sales['销售额'].min():,.2f} ({monthly_sales['销售额'].idxmin().strftime('%Y-%m')})    - 月均销售额: ¥{monthly_sales['销售额'].mean():,.2f}    3. 产品分析:    - 最畅销产品: {product_analysis.index[0][1]} (¥{product_analysis.iloc[0]['销售额']:,.2f})    - 最高利润产品: {product_analysis.sort_values('利润', ascending=False).index[0][1]}    - 产品类别数: {len(product_analysis.index.get_level_values('类别').unique())}    4. 客户分析:    - 高价值客户占比: {segment_stats.loc['高价值客户''客户数']/segment_stats['客户数'].sum():.1%}    - 平均客户生命周期价值: ¥{customer_analysis['总消费'].mean():,.2f}    - 客户回购率: {(customer_analysis['订单数'] > 1).sum()/len(customer_analysis):.1%}    5. 地理分析:    - 销售额最高城市: {city_analysis.index[0]} (¥{city_analysis.iloc[0]['销售额']:,.2f})    - 城市覆盖率: {len(city_analysis)} 个城市    6. 业务建议:    - 重点关注高价值客户维护    - 加大热销产品的库存和推广    - 在销售额高的城市增加营销投入    - 针对流失客户设计召回活动    """    print(report)    return {        'customers': customers,        'products': products,        'transactions': transactions,        'merged_data': merged_data,        'monthly_sales': monthly_sales,        'product_analysis': product_analysis,        'customer_analysis': customer_analysis,        'city_analysis': city_analysis,        'segment_stats': segment_stats,        'report': report    }# 执行电商案例ecommerce_analysis = ecommerce_case_study()

Pandas是Python数据科学生态系统的核心。掌握Pandas不仅是学习一个库,而是掌握了一套数据处理和分析的方法论。

明日将进入特征工程的世界,这是机器学习项目中最重要的环节之一。准备好将原始数据转化为机器学习模型的特征!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-07 15:17:43 HTTP/2.0 GET : https://f.mffb.com.cn/a/472787.html
  2. 运行时间 : 0.271232s [ 吞吐率:3.69req/s ] 内存消耗:4,851.02kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=cbb4b50bf34b72bd1ec4498b207eb0de
  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.000854s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001223s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000723s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.006480s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001309s ]
  6. SELECT * FROM `set` [ RunTime:0.048651s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000581s ]
  8. SELECT * FROM `article` WHERE `id` = 472787 LIMIT 1 [ RunTime:0.017787s ]
  9. UPDATE `article` SET `lasttime` = 1770448663 WHERE `id` = 472787 [ RunTime:0.005068s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.018157s ]
  11. SELECT * FROM `article` WHERE `id` < 472787 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.014444s ]
  12. SELECT * FROM `article` WHERE `id` > 472787 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.010647s ]
  13. SELECT * FROM `article` WHERE `id` < 472787 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008471s ]
  14. SELECT * FROM `article` WHERE `id` < 472787 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.007091s ]
  15. SELECT * FROM `article` WHERE `id` < 472787 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.014425s ]
0.272674s