Skip to content

Pandas 高级功能

概述

本章将深入探讨 Pandas 的高级功能,包括多级索引(MultiIndex)、时间序列分析、数据透视表、窗口函数、自定义函数应用等。这些高级特性能够帮助你处理更复杂的数据分析任务,提升数据处理的效率和灵活性。

1. 多级索引(MultiIndex)

1.1 创建多级索引

python
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import seaborn as sns

print("=== 多级索引基础 ===")

# 创建多级索引的几种方法
def create_multiindex_examples():
    """创建多级索引示例"""
    
    # 方法1: 使用arrays创建
    arrays = [['A', 'A', 'B', 'B'], ['one', 'two', 'one', 'two']]
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
    
    s1 = pd.Series(np.random.randn(4), index=index)
    print("方法1 - 使用arrays创建:")
    print(s1)
    print()
    
    # 方法2: 使用product创建
    from itertools import product
    index2 = pd.MultiIndex.from_product([['A', 'B'], ['one', 'two']], 
                                       names=['first', 'second'])
    s2 = pd.Series(np.random.randn(4), index=index2)
    print("方法2 - 使用product创建:")
    print(s2)
    print()
    
    # 方法3: 直接在DataFrame中创建
    df = pd.DataFrame({
        'A': [1, 2, 3, 4, 5, 6],
        'B': [10, 20, 30, 40, 50, 60],
        'C': ['X', 'Y', 'X', 'Y', 'X', 'Y']
    })
    
    # 设置多级索引
    df_multi = df.set_index(['C', 'A'])
    print("方法3 - DataFrame多级索引:")
    print(df_multi)
    print()
    
    return df_multi

df_multi = create_multiindex_examples()

1.2 多级索引操作

python
print("=== 多级索引操作 ===")

def multiindex_operations():
    """多级索引操作示例"""
    
    # 创建示例数据
    np.random.seed(42)
    dates = pd.date_range('2023-01-01', periods=12, freq='M')
    regions = ['北京', '上海', '广州']
    products = ['产品A', '产品B']
    
    # 创建多级索引DataFrame
    index = pd.MultiIndex.from_product([dates, regions, products], 
                                     names=['日期', '地区', '产品'])
    
    data = {
        '销售额': np.random.randint(1000, 10000, len(index)),
        '销量': np.random.randint(10, 100, len(index)),
        '利润率': np.random.uniform(0.1, 0.3, len(index))
    }
    
    df = pd.DataFrame(data, index=index)
    print("多级索引DataFrame:")
    print(df.head(10))
    print()
    
    # 索引选择
    print("1. 选择特定地区的数据:")
    beijing_data = df.loc[(slice(None), '北京', slice(None)), :]
    print(beijing_data.head())
    print()
    
    print("2. 选择特定产品的数据:")
    product_a = df.loc[(slice(None), slice(None), '产品A'), :]
    print(product_a.head())
    print()
    
    print("3. 交叉选择:")
    cross_selection = df.loc[('2023-01-31', '上海', '产品B'), :]
    print(cross_selection)
    print()
    
    # 索引层级操作
    print("4. 交换索引层级:")
    df_swapped = df.swaplevel('地区', '产品')
    print(df_swapped.head())
    print()
    
    print("5. 重置索引:")
    df_reset = df.reset_index()
    print(df_reset.head())
    print()
    
    return df

sales_df = multiindex_operations()

1.3 多级索引聚合分析

python
print("=== 多级索引聚合分析 ===")

def multiindex_aggregation(df):
    """多级索引聚合分析"""
    
    print("1. 按地区聚合:")
    region_agg = df.groupby(level='地区').agg({
        '销售额': ['sum', 'mean'],
        '销量': 'sum',
        '利润率': 'mean'
    })
    print(region_agg)
    print()
    
    print("2. 按产品聚合:")
    product_agg = df.groupby(level='产品').agg({
        '销售额': 'sum',
        '销量': 'sum',
        '利润率': 'mean'
    })
    print(product_agg)
    print()
    
    print("3. 按地区和产品聚合:")
    region_product_agg = df.groupby(level=['地区', '产品']).agg({
        '销售额': 'sum',
        '销量': 'sum'
    })
    print(region_product_agg)
    print()
    
    print("4. 时间序列聚合:")
    monthly_trend = df.groupby(level='日期').sum()
    print(monthly_trend.head())
    print()
    
    # 可视化多级索引数据
    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    # 地区销售额对比
    region_sales = df.groupby(level='地区')['销售额'].sum()
    region_sales.plot(kind='bar', ax=axes[0,0], color='skyblue')
    axes[0,0].set_title('各地区销售额对比')
    axes[0,0].set_ylabel('销售额')
    
    # 产品销售额对比
    product_sales = df.groupby(level='产品')['销售额'].sum()
    product_sales.plot(kind='pie', ax=axes[0,1], autopct='%1.1f%%')
    axes[0,1].set_title('产品销售额占比')
    
    # 月度销售趋势
    monthly_sales = df.groupby(level='日期')['销售额'].sum()
    monthly_sales.plot(ax=axes[1,0], marker='o')
    axes[1,0].set_title('月度销售趋势')
    axes[1,0].set_ylabel('销售额')
    axes[1,0].tick_params(axis='x', rotation=45)
    
    # 地区产品热力图
    pivot_data = df.groupby(['地区', '产品'])['销售额'].sum().unstack()
    sns.heatmap(pivot_data, annot=True, fmt='.0f', ax=axes[1,1], cmap='YlOrRd')
    axes[1,1].set_title('地区-产品销售额热力图')
    
    plt.tight_layout()
    plt.show()
    
    return region_product_agg

agg_result = multiindex_aggregation(sales_df)

2. 时间序列分析

2.1 时间序列基础操作

python
print("\n=== 时间序列分析 ===")

def time_series_basics():
    """时间序列基础操作"""
    
    # 创建时间序列数据
    dates = pd.date_range('2023-01-01', periods=365, freq='D')
    
    # 模拟股价数据
    np.random.seed(42)
    price_changes = np.random.normal(0, 1, 365)
    prices = 100 + np.cumsum(price_changes)
    
    # 模拟交易量
    volumes = np.random.randint(1000, 10000, 365)
    
    # 创建时间序列DataFrame
    ts_df = pd.DataFrame({
        '价格': prices,
        '交易量': volumes,
        '收益率': price_changes
    }, index=dates)
    
    print("时间序列数据:")
    print(ts_df.head())
    print()
    
    # 时间序列索引操作
    print("1. 选择特定月份数据:")
    jan_data = ts_df['2023-01']
    print(jan_data.head())
    print()
    
    print("2. 选择日期范围:")
    range_data = ts_df['2023-01-01':'2023-01-31']
    print(f"1月份数据点数: {len(range_data)}")
    print()
    
    print("3. 按工作日筛选:")
    weekday_data = ts_df[ts_df.index.weekday < 5]  # 0-4表示周一到周五
    print(f"工作日数据点数: {len(weekday_data)}")
    print()
    
    return ts_df

ts_data = time_series_basics()

2.2 时间序列重采样和频率转换

python
print("=== 时间序列重采样 ===")

def time_series_resampling(ts_df):
    """时间序列重采样示例"""
    
    print("1. 日数据转换为周数据:")
    weekly_data = ts_df.resample('W').agg({
        '价格': 'last',      # 周末价格
        '交易量': 'sum',     # 周交易量总和
        '收益率': 'sum'      # 周收益率
    })
    print(weekly_data.head())
    print()
    
    print("2. 日数据转换为月数据:")
    monthly_data = ts_df.resample('M').agg({
        '价格': 'last',
        '交易量': 'mean',
        '收益率': ['sum', 'std']
    })
    print(monthly_data.head())
    print()
    
    print("3. 向前填充和向后填充:")
    # 创建有缺失值的数据
    ts_missing = ts_df.copy()
    ts_missing.loc['2023-01-15':'2023-01-20', '价格'] = np.nan
    
    # 向前填充
    forward_fill = ts_missing['价格'].fillna(method='ffill')
    # 向后填充
    backward_fill = ts_missing['价格'].fillna(method='bfill')
    # 线性插值
    interpolated = ts_missing['价格'].interpolate()
    
    print("缺失值处理对比:")
    comparison = pd.DataFrame({
        '原始': ts_missing['价格']['2023-01-10':'2023-01-25'],
        '向前填充': forward_fill['2023-01-10':'2023-01-25'],
        '向后填充': backward_fill['2023-01-10':'2023-01-25'],
        '线性插值': interpolated['2023-01-10':'2023-01-25']
    })
    print(comparison)
    print()
    
    return weekly_data, monthly_data

weekly, monthly = time_series_resampling(ts_data)

2.3 移动窗口和滚动统计

python
print("=== 移动窗口分析 ===")

def rolling_window_analysis(ts_df):
    """移动窗口分析"""
    
    # 计算移动平均
    ts_df['MA_5'] = ts_df['价格'].rolling(window=5).mean()
    ts_df['MA_20'] = ts_df['价格'].rolling(window=20).mean()
    ts_df['MA_50'] = ts_df['价格'].rolling(window=50).mean()
    
    # 计算移动标准差(波动率)
    ts_df['波动率_20'] = ts_df['收益率'].rolling(window=20).std()
    
    # 计算布林带
    ts_df['布林上轨'] = ts_df['MA_20'] + 2 * ts_df['价格'].rolling(window=20).std()
    ts_df['布林下轨'] = ts_df['MA_20'] - 2 * ts_df['价格'].rolling(window=20).std()
    
    print("移动平均和布林带:")
    print(ts_df[['价格', 'MA_5', 'MA_20', 'MA_50', '布林上轨', '布林下轨']].head(60).tail(10))
    print()
    
    # 可视化技术指标
    fig, axes = plt.subplots(3, 1, figsize=(15, 12))
    
    # 价格和移动平均线
    ts_df[['价格', 'MA_5', 'MA_20', 'MA_50']].plot(ax=axes[0])
    axes[0].set_title('价格和移动平均线')
    axes[0].set_ylabel('价格')
    axes[0].legend()
    
    # 布林带
    axes[1].plot(ts_df.index, ts_df['价格'], label='价格', alpha=0.7)
    axes[1].plot(ts_df.index, ts_df['布林上轨'], label='布林上轨', linestyle='--')
    axes[1].plot(ts_df.index, ts_df['布林下轨'], label='布林下轨', linestyle='--')
    axes[1].fill_between(ts_df.index, ts_df['布林上轨'], ts_df['布林下轨'], alpha=0.2)
    axes[1].set_title('布林带')
    axes[1].set_ylabel('价格')
    axes[1].legend()
    
    # 波动率
    ts_df['波动率_20'].plot(ax=axes[2], color='red')
    axes[2].set_title('20日滚动波动率')
    axes[2].set_ylabel('波动率')
    
    plt.tight_layout()
    plt.show()
    
    # 计算更多技术指标
    print("技术指标统计:")
    technical_stats = {
        '当前价格': ts_df['价格'].iloc[-1],
        '5日均价': ts_df['MA_5'].iloc[-1],
        '20日均价': ts_df['MA_20'].iloc[-1],
        '50日均价': ts_df['MA_50'].iloc[-1],
        '当前波动率': ts_df['波动率_20'].iloc[-1],
        '价格相对20日均价': (ts_df['价格'].iloc[-1] / ts_df['MA_20'].iloc[-1] - 1) * 100
    }
    
    for indicator, value in technical_stats.items():
        print(f"{indicator}: {value:.2f}")
    print()
    
    return ts_df

ts_with_indicators = rolling_window_analysis(ts_data)

3. 数据透视表高级应用

3.1 复杂透视表创建

python
print("\n=== 高级数据透视表 ===")

def advanced_pivot_tables():
    """高级数据透视表应用"""
    
    # 创建复杂的销售数据
    np.random.seed(42)
    n_records = 1000
    
    data = {
        '日期': pd.date_range('2023-01-01', periods=n_records, freq='D'),
        '销售员': np.random.choice(['张三', '李四', '王五', '赵六'], n_records),
        '地区': np.random.choice(['华北', '华东', '华南', '华西'], n_records),
        '产品类别': np.random.choice(['电子产品', '服装', '食品', '家具'], n_records),
        '产品': np.random.choice(['产品A', '产品B', '产品C', '产品D', '产品E'], n_records),
        '销售额': np.random.randint(100, 5000, n_records),
        '数量': np.random.randint(1, 50, n_records),
        '成本': np.random.randint(50, 3000, n_records)
    }
    
    sales_data = pd.DataFrame(data)
    sales_data['利润'] = sales_data['销售额'] - sales_data['成本']
    sales_data['利润率'] = sales_data['利润'] / sales_data['销售额']
    sales_data['月份'] = sales_data['日期'].dt.to_period('M')
    sales_data['季度'] = sales_data['日期'].dt.to_period('Q')
    
    print("销售数据样本:")
    print(sales_data.head())
    print()
    
    # 1. 基础透视表
    print("1. 地区-产品类别透视表:")
    pivot1 = pd.pivot_table(sales_data, 
                           values='销售额', 
                           index='地区', 
                           columns='产品类别', 
                           aggfunc='sum',
                           fill_value=0)
    print(pivot1)
    print()
    
    # 2. 多值透视表
    print("2. 多指标透视表:")
    pivot2 = pd.pivot_table(sales_data,
                           values=['销售额', '利润', '数量'],
                           index='地区',
                           columns='产品类别',
                           aggfunc={'销售额': 'sum', '利润': 'sum', '数量': 'sum'},
                           fill_value=0)
    print(pivot2.head())
    print()
    
    # 3. 多级透视表
    print("3. 多级索引透视表:")
    pivot3 = pd.pivot_table(sales_data,
                           values='销售额',
                           index=['地区', '销售员'],
                           columns=['产品类别', '季度'],
                           aggfunc='sum',
                           fill_value=0)
    print(pivot3.head())
    print()
    
    # 4. 自定义聚合函数
    print("4. 自定义聚合函数透视表:")
    def profit_margin_avg(x):
        return (x.sum() if len(x) > 0 else 0)
    
    pivot4 = pd.pivot_table(sales_data,
                           values=['销售额', '利润率'],
                           index='销售员',
                           columns='地区',
                           aggfunc={'销售额': 'sum', '利润率': 'mean'},
                           fill_value=0)
    print(pivot4)
    print()
    
    return sales_data, pivot1, pivot2

sales_data, pivot1, pivot2 = advanced_pivot_tables()

3.2 透视表可视化和分析

python
print("=== 透视表可视化分析 ===")

def pivot_visualization(sales_data, pivot1):
    """透视表可视化分析"""
    
    fig, axes = plt.subplots(2, 2, figsize=(16, 12))
    
    # 1. 地区销售额堆叠柱状图
    pivot1.plot(kind='bar', stacked=True, ax=axes[0,0], colormap='Set3')
    axes[0,0].set_title('各地区产品类别销售额分布')
    axes[0,0].set_ylabel('销售额')
    axes[0,0].legend(title='产品类别', bbox_to_anchor=(1.05, 1), loc='upper left')
    
    # 2. 热力图
    sns.heatmap(pivot1, annot=True, fmt='.0f', ax=axes[0,1], cmap='YlOrRd')
    axes[0,1].set_title('地区-产品类别销售额热力图')
    
    # 3. 销售员业绩对比
    salesperson_performance = sales_data.groupby('销售员').agg({
        '销售额': 'sum',
        '利润': 'sum',
        '数量': 'sum'
    })
    
    salesperson_performance['销售额'].plot(kind='bar', ax=axes[1,0], color='skyblue')
    axes[1,0].set_title('销售员业绩对比')
    axes[1,0].set_ylabel('销售额')
    axes[1,0].tick_params(axis='x', rotation=45)
    
    # 4. 月度趋势分析
    monthly_trend = sales_data.groupby('月份').agg({
        '销售额': 'sum',
        '利润': 'sum'
    })
    
    monthly_trend.plot(ax=axes[1,1], marker='o')
    axes[1,1].set_title('月度销售和利润趋势')
    axes[1,1].set_ylabel('金额')
    axes[1,1].legend()
    
    plt.tight_layout()
    plt.show()
    
    # 生成透视表分析报告
    print("透视表分析报告:")
    print("=" * 50)
    
    # 地区分析
    region_total = pivot1.sum(axis=1).sort_values(ascending=False)
    print(f"最佳销售地区: {region_total.index[0]} (销售额: {region_total.iloc[0]:,.0f})")
    print(f"最差销售地区: {region_total.index[-1]} (销售额: {region_total.iloc[-1]:,.0f})")
    
    # 产品类别分析
    category_total = pivot1.sum(axis=0).sort_values(ascending=False)
    print(f"最佳产品类别: {category_total.index[0]} (销售额: {category_total.iloc[0]:,.0f})")
    print(f"最差产品类别: {category_total.index[-1]} (销售额: {category_total.iloc[-1]:,.0f})")
    
    # 销售员分析
    salesperson_ranking = sales_data.groupby('销售员')['销售额'].sum().sort_values(ascending=False)
    print(f"最佳销售员: {salesperson_ranking.index[0]} (销售额: {salesperson_ranking.iloc[0]:,.0f})")
    
    print("=" * 50)

pivot_visualization(sales_data, pivot1)

4. 窗口函数和滚动计算

4.1 滚动窗口函数

python
print("\n=== 窗口函数高级应用 ===")

def advanced_window_functions():
    """高级窗口函数应用"""
    
    # 创建时间序列数据
    dates = pd.date_range('2023-01-01', periods=100, freq='D')
    np.random.seed(42)
    
    df = pd.DataFrame({
        '日期': dates,
        '销售额': np.random.randint(1000, 5000, 100) + np.sin(np.arange(100) * 0.1) * 500,
        '访客数': np.random.randint(100, 1000, 100),
        '转化率': np.random.uniform(0.01, 0.1, 100)
    })
    
    df.set_index('日期', inplace=True)
    
    print("原始数据:")
    print(df.head())
    print()
    
    # 1. 基础滚动统计
    print("1. 基础滚动统计:")
    df['销售额_7日均值'] = df['销售额'].rolling(window=7).mean()
    df['销售额_7日标准差'] = df['销售额'].rolling(window=7).std()
    df['销售额_7日最大值'] = df['销售额'].rolling(window=7).max()
    df['销售额_7日最小值'] = df['销售额'].rolling(window=7).min()
    
    print(df[['销售额', '销售额_7日均值', '销售额_7日标准差']].head(10))
    print()
    
    # 2. 扩展窗口(累积统计)
    print("2. 扩展窗口统计:")
    df['累积销售额'] = df['销售额'].expanding().sum()
    df['累积平均销售额'] = df['销售额'].expanding().mean()
    df['累积最大销售额'] = df['销售额'].expanding().max()
    
    print(df[['销售额', '累积销售额', '累积平均销售额']].head(10))
    print()
    
    # 3. 自定义窗口函数
    print("3. 自定义窗口函数:")
    
    def coefficient_of_variation(x):
        """变异系数"""
        return x.std() / x.mean() if x.mean() != 0 else 0
    
    def percentile_75(x):
        """75分位数"""
        return x.quantile(0.75)
    
    df['销售额_7日变异系数'] = df['销售额'].rolling(window=7).apply(coefficient_of_variation)
    df['销售额_7日_75分位'] = df['销售额'].rolling(window=7).apply(percentile_75)
    
    print(df[['销售额', '销售额_7日变异系数', '销售额_7日_75分位']].head(15))
    print()
    
    # 4. 多列窗口计算
    print("4. 多列窗口计算:")
    df['销售效率'] = df['销售额'] / df['访客数']
    df['销售效率_7日均值'] = df['销售效率'].rolling(window=7).mean()
    
    # 相关性滚动计算
    df['销售额访客数_7日相关性'] = df['销售额'].rolling(window=7).corr(df['访客数'])
    
    print(df[['销售效率', '销售效率_7日均值', '销售额访客数_7日相关性']].head(15))
    print()
    
    return df

window_df = advanced_window_functions()

4.2 窗口函数可视化

python
print("=== 窗口函数可视化 ===")

def visualize_window_functions(df):
    """窗口函数结果可视化"""
    
    fig, axes = plt.subplots(3, 2, figsize=(16, 15))
    
    # 1. 原始数据vs滚动平均
    df[['销售额', '销售额_7日均值']].plot(ax=axes[0,0])
    axes[0,0].set_title('销售额 vs 7日滚动平均')
    axes[0,0].set_ylabel('销售额')
    axes[0,0].legend()
    
    # 2. 滚动标准差(波动性)
    df['销售额_7日标准差'].plot(ax=axes[0,1], color='red')
    axes[0,1].set_title('7日滚动标准差(波动性)')
    axes[0,1].set_ylabel('标准差')
    
    # 3. 累积统计
    df[['累积销售额', '累积平均销售额']].plot(ax=axes[1,0])
    axes[1,0].set_title('累积统计')
    axes[1,0].legend()
    
    # 4. 变异系数
    df['销售额_7日变异系数'].plot(ax=axes[1,1], color='green')
    axes[1,1].set_title('7日变异系数')
    axes[1,1].set_ylabel('变异系数')
    
    # 5. 销售效率
    df[['销售效率', '销售效率_7日均值']].plot(ax=axes[2,0])
    axes[2,0].set_title('销售效率及其滚动平均')
    axes[2,0].set_ylabel('销售效率')
    axes[2,0].legend()
    
    # 6. 滚动相关性
    df['销售额访客数_7日相关性'].plot(ax=axes[2,1], color='purple')
    axes[2,1].set_title('销售额与访客数7日滚动相关性')
    axes[2,1].set_ylabel('相关系数')
    axes[2,1].axhline(y=0, color='black', linestyle='--', alpha=0.5)
    
    plt.tight_layout()
    plt.show()
    
    # 窗口函数分析总结
    print("窗口函数分析总结:")
    print("=" * 50)
    
    latest_data = df.iloc[-1]
    print(f"最新销售额: {latest_data['销售额']:,.0f}")
    print(f"7日平均销售额: {latest_data['销售额_7日均值']:,.0f}")
    print(f"7日销售波动性: {latest_data['销售额_7日标准差']:,.2f}")
    print(f"累积总销售额: {latest_data['累积销售额']:,.0f}")
    print(f"当前销售效率: {latest_data['销售效率']:,.2f}")
    print(f"销售额与访客数相关性: {latest_data['销售额访客数_7日相关性']:,.3f}")
    
    # 趋势分析
    recent_trend = df['销售额_7日均值'].iloc[-7:].pct_change().mean()
    print(f"近期趋势 (7日平均增长率): {recent_trend:.2%}")
    
    print("=" * 50)

visualize_window_functions(window_df)

5. 自定义函数应用

5.1 apply、map、applymap函数

python
print("\n=== 自定义函数应用 ===")

def custom_function_applications():
    """自定义函数应用示例"""
    
    # 创建示例数据
    df = pd.DataFrame({
        '姓名': ['张三', '李四', '王五', '赵六', '钱七'],
        '年龄': [25, 30, 35, 28, 32],
        '工资': [8000, 12000, 15000, 9500, 11000],
        '部门': ['技术', '销售', '技术', '人事', '销售'],
        '入职日期': ['2020-01-15', '2019-03-20', '2018-07-10', '2021-02-28', '2020-09-05']
    })
    
    df['入职日期'] = pd.to_datetime(df['入职日期'])
    
    print("原始数据:")
    print(df)
    print()
    
    # 1. apply函数应用
    print("1. apply函数应用:")
    
    # 计算工作年限
    def calculate_work_years(hire_date):
        return (pd.Timestamp.now() - hire_date).days / 365.25
    
    df['工作年限'] = df['入职日期'].apply(calculate_work_years)
    
    # 工资等级分类
    def salary_grade(salary):
        if salary < 9000:
            return '初级'
        elif salary < 12000:
            return '中级'
        else:
            return '高级'
    
    df['工资等级'] = df['工资'].apply(salary_grade)
    
    print(df[['姓名', '工资', '工资等级', '工作年限']])
    print()
    
    # 2. 多列apply应用
    print("2. 多列apply应用:")
    
    def performance_score(row):
        """综合绩效评分"""
        base_score = 60
        
        # 工资加分
        if row['工资'] > 12000:
            base_score += 20
        elif row['工资'] > 10000:
            base_score += 10
        
        # 工作年限加分
        if row['工作年限'] > 3:
            base_score += 15
        elif row['工作年限'] > 1:
            base_score += 10
        
        # 年龄调整
        if 25 <= row['年龄'] <= 35:
            base_score += 5
        
        return min(base_score, 100)  # 最高100分
    
    df['绩效评分'] = df.apply(performance_score, axis=1)
    
    print(df[['姓名', '绩效评分']])
    print()
    
    # 3. map函数应用
    print("3. map函数应用:")
    
    # 部门映射
    department_mapping = {
        '技术': 'Technology',
        '销售': 'Sales',
        '人事': 'HR'
    }
    
    df['部门_英文'] = df['部门'].map(department_mapping)
    
    print(df[['姓名', '部门', '部门_英文']])
    print()
    
    # 4. 复杂数据处理
    print("4. 复杂数据处理:")
    
    # 创建包含复杂数据的DataFrame
    complex_df = pd.DataFrame({
        'A': [1, 2, 3, 4, 5],
        'B': [10.5, 20.3, 30.7, 40.2, 50.9],
        'C': ['apple', 'banana', 'cherry', 'date', 'elderberry']
    })
    
    # applymap应用于整个DataFrame
    def format_value(x):
        if isinstance(x, (int, float)):
            return f"{x:.1f}"
        else:
            return x.upper()
    
    formatted_df = complex_df.applymap(format_value)
    print("格式化后的DataFrame:")
    print(formatted_df)
    print()
    
    return df

employee_df = custom_function_applications()

5.2 向量化操作和性能优化

python
print("=== 向量化操作和性能优化 ===")

def vectorization_examples():
    """向量化操作示例"""
    
    # 创建大型数据集进行性能测试
    n = 100000
    np.random.seed(42)
    
    large_df = pd.DataFrame({
        'A': np.random.randint(1, 100, n),
        'B': np.random.randint(1, 100, n),
        'C': np.random.uniform(0, 1, n)
    })
    
    print(f"测试数据集大小: {len(large_df):,} 行")
    print()
    
    # 性能对比:循环 vs 向量化
    import time
    
    print("性能对比测试:")
    
    # 方法1: 使用循环(慢)
    start_time = time.time()
    result1 = []
    for i in range(len(large_df)):
        if large_df.iloc[i]['A'] > large_df.iloc[i]['B']:
            result1.append(large_df.iloc[i]['A'] * large_df.iloc[i]['C'])
        else:
            result1.append(large_df.iloc[i]['B'] * large_df.iloc[i]['C'])
    loop_time = time.time() - start_time
    
    # 方法2: 使用向量化操作(快)
    start_time = time.time()
    result2 = np.where(large_df['A'] > large_df['B'], 
                      large_df['A'] * large_df['C'], 
                      large_df['B'] * large_df['C'])
    vectorized_time = time.time() - start_time
    
    # 方法3: 使用pandas向量化
    start_time = time.time()
    result3 = large_df.apply(lambda row: row['A'] * row['C'] if row['A'] > row['B'] 
                           else row['B'] * row['C'], axis=1)
    pandas_apply_time = time.time() - start_time
    
    print(f"循环方法耗时: {loop_time:.4f} 秒")
    print(f"NumPy向量化耗时: {vectorized_time:.4f} 秒")
    print(f"Pandas apply耗时: {pandas_apply_time:.4f} 秒")
    print(f"向量化比循环快: {loop_time/vectorized_time:.1f} 倍")
    print()
    
    # 复杂向量化操作示例
    print("复杂向量化操作示例:")
    
    # 创建示例数据
    df = pd.DataFrame({
        '销售额': np.random.randint(1000, 10000, 1000),
        '成本': np.random.randint(500, 8000, 1000),
        '地区': np.random.choice(['北京', '上海', '广州', '深圳'], 1000),
        '产品类型': np.random.choice(['A', 'B', 'C'], 1000)
    })
    
    # 复杂的业务逻辑向量化
    conditions = [
        (df['销售额'] > 8000) & (df['地区'].isin(['北京', '上海'])),
        (df['销售额'] > 5000) & (df['地区'].isin(['广州', '深圳'])),
        df['销售额'] > 3000
    ]
    
    choices = ['优秀', '良好', '一般']
    
    df['业绩等级'] = np.select(conditions, choices, default='待改进')
    
    # 计算复杂指标
    df['利润'] = df['销售额'] - df['成本']
    df['利润率'] = df['利润'] / df['销售额']
    
    # 地区调整系数
    region_multiplier = {'北京': 1.2, '上海': 1.15, '广州': 1.1, '深圳': 1.05}
    df['调整后销售额'] = df['销售额'] * df['地区'].map(region_multiplier)
    
    print("向量化处理结果:")
    print(df.head())
    print()
    
    # 性能分析总结
    performance_summary = df.groupby(['地区', '业绩等级']).agg({
        '销售额': ['count', 'mean', 'sum'],
        '利润率': 'mean'
    }).round(2)
    
    print("业绩分析汇总:")
    print(performance_summary)
    
    return df

vectorized_df = vectorization_examples()

本章小结

本章深入介绍了 Pandas 的高级功能:

核心内容回顾

  1. 多级索引(MultiIndex):创建、操作和聚合分析
  2. 时间序列分析:重采样、频率转换、移动窗口
  3. 高级数据透视表:复杂透视、多维分析、可视化
  4. 窗口函数:滚动计算、扩展窗口、自定义函数
  5. 自定义函数应用:apply、map、applymap和向量化优化

关键技能

  • 处理复杂的层次化数据结构
  • 进行专业的时间序列分析
  • 创建多维数据透视和交叉分析
  • 实现高效的滚动计算和技术指标
  • 编写高性能的数据处理代码

最佳实践

  • 优先使用向量化操作提升性能
  • 合理选择窗口大小和聚合函数
  • 利用多级索引简化复杂数据操作
  • 结合可视化增强数据洞察
  • 注意内存使用和计算效率

实际应用场景

  • 金融数据分析和技术指标计算
  • 多维业务数据的交叉分析
  • 时间序列预测和趋势分析
  • 复杂报表和仪表板开发
  • 大数据处理和性能优化

掌握这些高级功能,能够帮助你:

  • 处理更复杂的数据分析任务
  • 提升数据处理的效率和质量
  • 构建专业的数据分析解决方案
  • 深入挖掘数据中的商业价值

练习题

  1. 创建一个包含多级索引的销售数据分析系统
  2. 实现一套完整的股票技术分析指标
  3. 设计一个多维度的业务数据透视分析工具
  4. 开发高性能的大数据处理流程
  5. 构建一个时间序列预测模型

下一章我们将学习 Pandas 的性能优化技巧,探索如何处理大规模数据和提升计算效率。