引言:为什么需要进阶数据分析技能?

在当今数据驱动的时代,Python已成为数据分析领域的首选语言。然而,许多初学者在掌握了基础的Pandas和Matplotlib后,常常陷入瓶颈——面对复杂的数据清洗、高级可视化需求或大规模数据处理时感到无从下手。本课程将带你从基础走向实战,系统性地掌握数据处理与可视化的核心技能。

学习目标

  • 掌握Pandas高级数据操作技巧
  • 熟练使用Seaborn进行统计可视化
  • 学会处理缺失值、异常值等复杂数据问题
  • 掌握时间序列分析基础
  • 能够使用Plotly创建交互式可视化
  • 完成一个完整的数据分析项目

第一部分:Pandas高级数据操作

1.1 多级索引(MultiIndex)的使用

多级索引是处理高维数据的强大工具,特别适合处理具有层次结构的数据。

import pandas as pd
import numpy as np

# 创建示例数据
data = {
    '地区': ['北京', '北京', '上海', '上海', '广州', '广州'],
    '季度': ['Q1', 'Q2', 'Q1', 'Q2', 'Q1', 'Q2'],
    '销售额': [120, 150, 180, 200, 90, 110],
    '利润': [30, 40, 50, 60, 20, 25]
}

df = pd.DataFrame(data)
print("原始数据:")
print(df)

# 创建多级索引
df_multi = df.set_index(['地区', '季度'])
print("\n多级索引数据:")
print(df_multi)

# 多级索引的查询
print("\n查询北京地区的数据:")
print(df_multi.loc['北京'])

print("\n查询北京Q1季度的销售额:")
print(df_multi.loc[('北京', 'Q1'), '销售额'])

# 多级索引的聚合
print("\n按地区计算平均销售额:")
print(df_multi.groupby(level='地区')['销售额'].mean())

print("\n按季度计算总利润:")
print(df_multi.groupby(level='季度')['利润'].sum())

1.2 高效的分组操作

分组操作是数据分析中最常用的操作之一,掌握高效的分组技巧能大幅提升分析效率。

# 使用transform进行分组计算
df['地区平均销售额'] = df.groupby('地区')['销售额'].transform('mean')
print("\n添加地区平均销售额列:")
print(df)

# 使用agg进行多指标聚合
agg_result = df.groupby('地区').agg({
    '销售额': ['sum', 'mean', 'max'],
    '利润': ['sum', 'mean']
})
print("\n多指标聚合结果:")
print(agg_result)

# 自定义聚合函数
def profit_margin(series):
    return series['利润'].sum() / series['销售额'].sum() * 100

margin_result = df.groupby('地区').apply(profit_margin)
print("\n各地区利润率:")
print(margin_result)

1.3 数据合并与连接

处理多个数据源时,数据合并是必不可少的技能。

# 创建两个数据集
df1 = pd.DataFrame({
    '产品ID': ['A001', 'A002', 'A003'],
    '产品名称': ['笔记本', '手机', '平板'],
    '价格': [5000, 3000, 2000]
})

df2 = pd.DataFrame({
    '产品ID': ['A001', 'A002', 'A004'],
    '销量': [100, 200, 50],
    '地区': ['北京', '上海', '广州']
})

# 内连接
inner_join = pd.merge(df1, df2, on='产品ID', how='inner')
print("内连接结果:")
print(inner_join)

# 左连接
left_join = pd.merge(df1, df2, on='产品ID', how='left')
print("\n左连接结果:")
print(left_join)

# 外连接
outer_join = pd.merge(df1, df2, on='产品ID', how='outer')
print("\n外连接结果:")
print(outer_join)

# 索引连接
df1_indexed = df1.set_index('产品ID')
df2_indexed = df2.set_index('产品ID')
index_join = df1_indexed.join(df2_indexed, how='inner')
print("\n索引连接结果:")
print(index_join)

第二部分:高级数据清洗技巧

2.1 缺失值处理的高级策略

缺失值处理不仅仅是简单的填充或删除,需要根据数据特点和业务场景选择合适的方法。

# 创建包含缺失值的数据集
np.random.seed(42)
data = {
    '年龄': [25, 30, np.nan, 35, 40, np.nan, 45],
    '收入': [50000, 60000, 70000, np.nan, 80000, 90000, 100000],
    '城市': ['北京', '上海', '北京', '上海', np.nan, '广州', '广州'],
    '评分': [4.5, 3.8, 4.2, 4.7, 4.0, 4.3, np.nan]
}
df_missing = pd.DataFrame(data)
print("原始数据(含缺失值):")
print(df_missing)

# 1. 检查缺失值情况
print("\n缺失值统计:")
print(df_missing.isnull().sum())

# 2. 基于统计的填充
# 使用中位数填充数值型数据
df_missing['年龄_中位数填充'] = df_missing['年龄'].fillna(df_missing['年龄'].median())
print("\n年龄中位数填充结果:")
print(df_missing[['年龄', '年龄_中位数填充']])

# 3. 基于分组的填充
df_missing['收入_分组填充'] = df_missing.groupby('城市')['收入'].transform(
    lambda x: x.fillna(x.median())
)
print("\n按城市分组填充收入:")
print(df_missing[['城市', '收入', '收入_分组填充']])

# 4. 使用插值法
df_missing['年龄_插值填充'] = df_missing['年龄'].interpolate(method='linear')
print("\n线性插值填充年龄:")
print(df_missing[['年龄', '年龄_插值填充']])

# 5. 使用KNN填充(需要sklearn)
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=2)
df_numeric = df_missing[['年龄', '收入', '评分']].copy()
df_filled = pd.DataFrame(imputer.fit_transform(df_numeric), 
                        columns=df_numeric.columns)
print("\nKNN填充结果:")
print(df_filled)

2.2 异常值检测与处理

异常值可能严重影响分析结果,需要科学地检测和处理。

# 创建包含异常值的数据集
np.random.seed(42)
normal_data = np.random.normal(100, 15, 100)
outliers = np.array([500, 600, 700, 800])
data = np.concatenate([normal_data, outliers])
df_outlier = pd.DataFrame({'数值': data})

# 1. 基于标准差的检测
mean = df_outlier['数值'].mean()
std = df_outlier['数值'].std()
z_scores = (df_outlier['数值'] - mean) / std
outliers_std = df_outlier[abs(z_scores) > 3]
print("基于标准差检测的异常值:")
print(outliers_std)

# 2. 基于IQR的检测
Q1 = df_outlier['数值'].quantile(0.25)
Q3 = df_outlier['数值'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers_iqr = df_outlier[(df_outlier['数值'] < lower_bound) | 
                          (df_outlier['数值'] > upper_bound)]
print("\n基于IQR检测的异常值:")
print(outliers_iqr)

# 3. 基于孤立森林的检测(机器学习方法)
from sklearn.ensemble import IsolationForest
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outliers_iso = iso_forest.fit_predict(df_outlier)
df_outlier['异常标记'] = outliers_iso
print("\n基于孤立森林的异常值检测:")
print(df_outlier[df_outlier['异常标记'] == -1])

# 4. 异常值处理策略
# 策略1:删除
df_clean = df_outlier[abs(z_scores) <= 3].copy()
print(f"\n删除异常值后剩余数据量:{len(df_clean)}")

# 策略2:Winsorization(缩尾处理)
def winsorize(series, limits=[0.05, 0.05]):
    lower = series.quantile(limits[0])
    upper = series.quantile(1 - limits[1])
    return series.clip(lower=lower, upper=upper)

df_outlier['数值_缩尾'] = winsorize(df_outlier['数值'])
print("\n缩尾处理后的数据:")
print(df_outlier[['数值', '数值_缩尾']].tail(10))

第三部分:高级可视化技术

3.1 Seaborn高级统计可视化

Seaborn是基于Matplotlib的统计可视化库,提供了更美观的默认样式和更高级的统计图表。

import seaborn as sns
import matplotlib.pyplot as plt

# 设置样式
sns.set_theme(style="whitegrid")

# 创建示例数据
np.random.seed(42)
data = {
    '类别': np.random.choice(['A', 'B', 'C', 'D'], 200),
    '数值': np.random.normal(100, 20, 200),
    '分组': np.random.choice(['X', 'Y'], 200)
}
df_viz = pd.DataFrame(data)

# 1. 分布可视化
plt.figure(figsize=(12, 8))

# 小提琴图
plt.subplot(2, 2, 1)
sns.violinplot(data=df_viz, x='类别', y='数值', hue='分组', split=True)
plt.title('小提琴图:分布与分组比较')

# 箱线图
plt.subplot(2, 2, 2)
sns.boxplot(data=df_viz, x='类别', y='数值', hue='分组')
plt.title('箱线图:统计摘要')

# 点图
plt.subplot(2, 2, 3)
sns.pointplot(data=df_viz, x='类别', y='数值', hue='分组', 
              capsize=0.1, errwidth=1.5)
plt.title('点图:均值与置信区间')

# 小提琴图+箱线图组合
plt.subplot(2, 2, 4)
sns.violinplot(data=df_viz, x='类别', y='数值', inner='box')
plt.title('小提琴图+箱线图')

plt.tight_layout()
plt.show()

# 2. 关系可视化
plt.figure(figsize=(12, 5))

# 散点图矩阵
plt.subplot(1, 2, 1)
sns.scatterplot(data=df_viz, x='数值', y='数值', hue='类别', 
                size='分组', sizes=(50, 200))
plt.title('散点图:多维度关系')

# 回归图
plt.subplot(1, 2, 2)
sns.regplot(data=df_viz, x='数值', y='数值', 
            scatter_kws={'alpha':0.5}, line_kws={'color':'red'})
plt.title('回归图:线性关系')

plt.tight_layout()
plt.show()

3.2 Plotly交互式可视化

Plotly是创建交互式可视化的强大工具,特别适合在网页或仪表板中展示。

import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 1. 基础交互式图表
# 创建示例数据
df_plotly = pd.DataFrame({
    '城市': ['北京', '上海', '广州', '深圳', '杭州'],
    'GDP': [36103, 38701, 25019, 26927, 16106],
    '人口': [2154, 2424, 1531, 1756, 1194],
    '人均GDP': [16760, 15960, 16340, 15330, 13500]
})

# 散点图
fig1 = px.scatter(df_plotly, x='人口', y='GDP', 
                  size='人均GDP', color='城市',
                  hover_name='城市', hover_data=['人均GDP'],
                  title='城市GDP与人口关系')
fig1.show()

# 2. 高级交互式图表
# 创建时间序列数据
dates = pd.date_range('2023-01-01', periods=30, freq='D')
df_time = pd.DataFrame({
    '日期': dates,
    '销售额': np.random.normal(1000, 200, 30).cumsum(),
    '利润': np.random.normal(200, 50, 30).cumsum()
})

# 创建子图
fig2 = make_subplots(rows=1, cols=2, 
                     subplot_titles=('销售额趋势', '利润趋势'))

# 添加销售额曲线
fig2.add_trace(
    go.Scatter(x=df_time['日期'], y=df_time['销售额'],
               mode='lines+markers', name='销售额'),
    row=1, col=1
)

# 添加利润曲线
fig2.add_trace(
    go.Scatter(x=df_time['日期'], y=df_time['利润'],
               mode='lines+markers', name='利润'),
    row=1, col=2
)

# 更新布局
fig2.update_layout(
    title_text="时间序列分析",
    showlegend=True,
    height=400
)

fig2.show()

# 3. 3D交互式可视化
df_3d = pd.DataFrame({
    'x': np.random.normal(0, 1, 100),
    'y': np.random.normal(0, 1, 100),
    'z': np.random.normal(0, 1, 100),
    '类别': np.random.choice(['A', 'B', 'C'], 100)
})

fig3 = px.scatter_3d(df_3d, x='x', y='y', z='z',
                     color='类别', hover_data=['类别'],
                     title='3D散点图')
fig3.show()

第四部分:时间序列分析基础

4.1 时间序列数据处理

时间序列数据在金融、销售、气象等领域广泛应用,需要特殊的处理方法。

# 创建时间序列数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=365, freq='D')
values = np.random.normal(100, 10, 365) + np.sin(np.arange(365) * 2 * np.pi / 365) * 20

df_ts = pd.DataFrame({
    '日期': dates,
    '销售额': values
})
df_ts.set_index('日期', inplace=True)

print("时间序列数据前5行:")
print(df_ts.head())

# 1. 重采样(Resampling)
# 按周重采样
weekly = df_ts.resample('W').sum()
print("\n周销售额:")
print(weekly.head())

# 按月重采样
monthly = df_ts.resample('M').mean()
print("\n月平均销售额:")
print(monthly.head())

# 2. 滚动窗口计算
df_ts['7天移动平均'] = df_ts['销售额'].rolling(window=7).mean()
df_ts['30天移动平均'] = df_ts['销售额'].rolling(window=30).mean()
df_ts['7天标准差'] = df_ts['销售额'].rolling(window=7).std()

print("\n添加滚动统计量:")
print(df_ts[['销售额', '7天移动平均', '30天移动平均', '7天标准差']].head(10))

# 3. 季节性分解
from statsmodels.tsa.seasonal import seasonal_decompose

# 需要确保数据是连续的
df_ts_clean = df_ts.asfreq('D').fillna(method='ffill')
decomposition = seasonal_decompose(df_ts_clean['销售额'], model='additive', period=30)

# 可视化分解结果
fig, axes = plt.subplots(4, 1, figsize=(12, 10))
decomposition.observed.plot(ax=axes[0], title='原始数据')
decomposition.trend.plot(ax=axes[1], title='趋势')
decomposition.seasonal.plot(ax=axes[2], title='季节性')
decomposition.resid.plot(ax=axes[3], title='残差')
plt.tight_layout()
plt.show()

4.2 时间序列预测基础

from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error

# 准备数据
train_size = int(len(df_ts) * 0.8)
train, test = df_ts.iloc[:train_size], df_ts.iloc[train_size:]

# 拟合ARIMA模型
model = ARIMA(train['销售额'], order=(1, 1, 1))
model_fit = model.fit()
print(model_fit.summary())

# 预测
forecast = model_fit.forecast(steps=len(test))
forecast_index = pd.date_range(start=test.index[0], periods=len(test), freq='D')
forecast_series = pd.Series(forecast, index=forecast_index)

# 评估
mse = mean_squared_error(test['销售额'], forecast)
print(f"\n预测均方误差:{mse:.2f}")

# 可视化
plt.figure(figsize=(12, 6))
plt.plot(train.index, train['销售额'], label='训练数据')
plt.plot(test.index, test['销售额'], label='测试数据')
plt.plot(forecast_series.index, forecast_series, label='预测数据', color='red')
plt.title('ARIMA模型预测')
plt.legend()
plt.show()

第五部分:实战项目:电商销售数据分析

5.1 项目背景与数据准备

我们将分析一个模拟的电商销售数据集,包含订单、产品、客户等信息。

# 创建模拟数据
np.random.seed(42)

# 订单数据
orders = pd.DataFrame({
    '订单ID': range(1000, 2000),
    '客户ID': np.random.randint(100, 500, 1000),
    '产品ID': np.random.randint(1, 50, 1000),
    '数量': np.random.randint(1, 10, 1000),
    '单价': np.random.uniform(10, 1000, 1000).round(2),
    '订单日期': pd.date_range('2023-01-01', periods=1000, freq='H')
})

# 产品数据
products = pd.DataFrame({
    '产品ID': range(1, 51),
    '产品名称': [f'产品_{i}' for i in range(1, 51)],
    '类别': np.random.choice(['电子产品', '服装', '家居', '食品'], 50),
    '成本': np.random.uniform(5, 500, 50).round(2)
})

# 客户数据
customers = pd.DataFrame({
    '客户ID': range(100, 500),
    '城市': np.random.choice(['北京', '上海', '广州', '深圳', '杭州'], 400),
    '注册日期': pd.date_range('2022-01-01', periods=400, freq='D')
})

print("数据准备完成")
print(f"订单数:{len(orders)}")
print(f"产品数:{len(products)}")
print(f"客户数:{len(customers)}")

5.2 数据整合与清洗

# 计算订单总金额
orders['总金额'] = orders['数量'] * orders['单价']

# 合并数据
# 订单与产品合并
orders_products = pd.merge(orders, products, on='产品ID', how='left')

# 与客户合并
full_data = pd.merge(orders_products, customers, on='客户ID', how='left')

# 计算利润
full_data['利润'] = full_data['总金额'] - (full_data['数量'] * full_data['成本'])

print("\n数据整合完成")
print(full_data.head())

# 检查缺失值
print("\n缺失值统计:")
print(full_data.isnull().sum())

# 处理缺失值(如果有)
full_data = full_data.dropna()  # 这里简单删除,实际项目中应根据情况处理

# 数据类型转换
full_data['订单日期'] = pd.to_datetime(full_data['订单日期'])
full_data['注册日期'] = pd.to_datetime(full_data['注册日期'])

5.3 探索性数据分析

# 1. 销售趋势分析
# 按月汇总
monthly_sales = full_data.groupby(full_data['订单日期'].dt.to_period('M')).agg({
    '总金额': 'sum',
    '利润': 'sum',
    '订单ID': 'count'
}).rename(columns={'订单ID': '订单数'})

print("月度销售汇总:")
print(monthly_sales)

# 2. 产品类别分析
category_analysis = full_data.groupby('类别').agg({
    '总金额': ['sum', 'mean'],
    '利润': 'sum',
    '数量': 'sum'
})
print("\n产品类别分析:")
print(category_analysis)

# 3. 客户分析
customer_analysis = full_data.groupby('客户ID').agg({
    '总金额': 'sum',
    '利润': 'sum',
    '订单ID': 'count'
}).rename(columns={'订单ID': '订单数'})
customer_analysis['平均订单金额'] = customer_analysis['总金额'] / customer_analysis['订单数']

print("\n客户分析:")
print(customer_analysis.head())

5.4 高级可视化分析

# 1. 销售趋势可视化
plt.figure(figsize=(15, 10))

# 月度销售趋势
plt.subplot(2, 2, 1)
monthly_sales['总金额'].plot(kind='line', marker='o')
plt.title('月度销售额趋势')
plt.xlabel('月份')
plt.ylabel('销售额')

# 产品类别销售占比
plt.subplot(2, 2, 2)
category_sum = full_data.groupby('类别')['总金额'].sum()
plt.pie(category_sum, labels=category_sum.index, autopct='%1.1f%%')
plt.title('产品类别销售占比')

# 客户城市分布
plt.subplot(2, 2, 3)
city_sales = full_data.groupby('城市')['总金额'].sum()
city_sales.plot(kind='bar')
plt.title('各城市销售额')
plt.xticks(rotation=45)

# 利润分布
plt.subplot(2, 2, 4)
plt.hist(full_data['利润'], bins=30, alpha=0.7, edgecolor='black')
plt.title('利润分布')
plt.xlabel('利润')
plt.ylabel('频数')

plt.tight_layout()
plt.show()

# 2. 交互式可视化
# 使用Plotly创建交互式仪表板
fig = make_subplots(
    rows=2, cols=2,
    subplot_titles=('销售额趋势', '类别占比', '城市销售', '利润分布'),
    specs=[[{"type": "scatter"}, {"type": "pie"}],
           [{"type": "bar"}, {"type": "histogram"}]]
)

# 销售额趋势
fig.add_trace(
    go.Scatter(x=monthly_sales.index.astype(str), y=monthly_sales['总金额'],
               mode='lines+markers', name='销售额'),
    row=1, col=1
)

# 类别占比
fig.add_trace(
    go.Pie(labels=category_sum.index, values=category_sum.values,
           name='类别占比'),
    row=1, col=2
)

# 城市销售
fig.add_trace(
    go.Bar(x=city_sales.index, y=city_sales.values, name='城市销售'),
    row=2, col=1
)

# 利润分布
fig.add_trace(
    go.Histogram(x=full_data['利润'], nbinsx=30, name='利润分布'),
    row=2, col=2
)

fig.update_layout(
    title_text="电商销售数据分析仪表板",
    height=800,
    showlegend=False
)

fig.show()

5.5 关键业务洞察

# 1. 计算RFM指标(最近购买时间、购买频率、购买金额)
# 最近购买时间(Recency)
recency = full_data.groupby('客户ID')['订单日期'].max()
recency = (pd.Timestamp('2023-12-31') - recency).dt.days

# 购买频率(Frequency)
frequency = full_data.groupby('客户ID')['订单ID'].nunique()

# 购买金额(Monetary)
monetary = full_data.groupby('客户ID')['总金额'].sum()

rfm = pd.DataFrame({
    'Recency': recency,
    'Frequency': frequency,
    'Monetary': monetary
})

# RFM评分(1-5分)
rfm['R_Score'] = pd.qcut(rfm['Recency'], 5, labels=[5, 4, 3, 2, 1])
rfm['F_Score'] = pd.qcut(rfm['Frequency'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5])
rfm['M_Score'] = pd.qcut(rfm['Monetary'], 5, labels=[1, 2, 3, 4, 5])

# RFM总分
rfm['RFM_Score'] = rfm['R_Score'].astype(int) + rfm['F_Score'].astype(int) + rfm['M_Score'].astype(int)

print("RFM分析结果:")
print(rfm.head())

# 2. 客户分群
def customer_segment(rfm_score):
    if rfm_score >= 12:
        return '高价值客户'
    elif rfm_score >= 9:
        return '中价值客户'
    elif rfm_score >= 6:
        return '低价值客户'
    else:
        return '流失风险客户'

rfm['客户分群'] = rfm['RFM_Score'].apply(customer_segment)
print("\n客户分群统计:")
print(rfm['客户分群'].value_counts())

# 3. 分群可视化
plt.figure(figsize=(10, 6))
segment_counts = rfm['客户分群'].value_counts()
plt.pie(segment_counts, labels=segment_counts.index, autopct='%1.1f%%')
plt.title('客户分群分布')
plt.show()

第六部分:性能优化与大数据处理

6.1 Pandas性能优化技巧

# 1. 使用适当的数据类型
def optimize_memory(df):
    """优化DataFrame内存使用"""
    df_optimized = df.copy()
    
    for col in df_optimized.columns:
        col_type = df_optimized[col].dtype
        
        if col_type != object:
            c_min = df_optimized[col].min()
            c_max = df_optimized[col].max()
            
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df_optimized[col] = df_optimized[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df_optimized[col] = df_optimized[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df_optimized[col] = df_optimized[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df_optimized[col] = df_optimized[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df_optimized[col] = df_optimized[col].astype(np.float32)
                else:
                    df_optimized[col] = df_optimized[col].astype(np.float64)
        else:
            df_optimized[col] = df_optimized[col].astype('category')
    
    return df_optimized

# 2. 使用向量化操作代替循环
# 慢速循环方式
def slow_calculation(df):
    result = []
    for i in range(len(df)):
        if df.iloc[i]['销售额'] > 100:
            result.append(df.iloc[i]['销售额'] * 1.1)
        else:
            result.append(df.iloc[i]['销售额'] * 0.9)
    return result

# 快速向量化方式
def fast_calculation(df):
    return np.where(df['销售额'] > 100, df['销售额'] * 1.1, df['销售额'] * 0.9)

# 3. 使用eval和query进行高效计算
df_large = pd.DataFrame({
    'A': np.random.randn(1000000),
    'B': np.random.randn(1000000),
    'C': np.random.randn(1000000)
})

# 使用eval进行高效计算
df_large['D'] = df_large.eval('A * B + C')
df_large['E'] = df_large.eval('A > 0 & B > 0')

# 使用query进行高效筛选
result = df_large.query('A > 0 & B > 0 & C > 0')

6.2 处理大数据集

# 1. 分块处理(Chunking)
def process_large_file(file_path, chunk_size=100000):
    """分块处理大文件"""
    chunks = []
    for chunk in pd.read_csv(file_path, chunksize=chunk_size):
        # 对每个chunk进行处理
        processed_chunk = chunk.dropna().reset_index(drop=True)
        chunks.append(processed_chunk)
    
    # 合并结果
    result = pd.concat(chunks, ignore_index=True)
    return result

# 2. 使用Dask进行并行处理
try:
    import dask.dataframe as dd
    
    # 创建Dask DataFrame
    ddf = dd.from_pandas(df_large, npartitions=4)
    
    # 执行并行计算
    result = ddf.groupby('A').mean().compute()
    print("Dask并行计算结果:")
    print(result.head())
    
except ImportError:
    print("Dask未安装,跳过Dask示例")

# 3. 使用Vaex处理超大数据集
try:
    import vaex
    
    # 创建Vaex DataFrame(内存映射,不加载全部数据)
    df_vaex = vaex.from_pandas(df_large)
    
    # 执行计算
    result_vaex = df_vaex.groupby('A', agg='mean')
    print("Vaex计算结果:")
    print(result_vaex.head())
    
except ImportError:
    print("Vaex未安装,跳过Vaex示例")

第七部分:实战项目进阶:时间序列预测

7.1 数据准备与特征工程

# 创建更复杂的时间序列数据
np.random.seed(42)
dates = pd.date_range('2020-01-01', periods=1000, freq='D')

# 基础趋势
trend = np.linspace(100, 200, 1000)

# 季节性
seasonal = 20 * np.sin(2 * np.pi * np.arange(1000) / 365)

# 周期性
periodic = 10 * np.sin(2 * np.pi * np.arange(1000) / 30)

# 随机噪声
noise = np.random.normal(0, 5, 1000)

# 合成数据
values = trend + seasonal + periodic + noise

df_ts_complex = pd.DataFrame({
    '日期': dates,
    '销售额': values
})
df_ts_complex.set_index('日期', inplace=True)

print("复杂时间序列数据前5行:")
print(df_ts_complex.head())

7.2 特征工程

# 1. 创建滞后特征
for lag in [1, 7, 30]:
    df_ts_complex[f'lag_{lag}'] = df_ts_complex['销售额'].shift(lag)

# 2. 创建移动统计特征
df_ts_complex['rolling_mean_7'] = df_ts_complex['销售额'].rolling(window=7).mean()
df_ts_complex['rolling_std_7'] = df_ts_complex['销售额'].rolling(window=7).std()

# 3. 创建时间特征
df_ts_complex['day_of_week'] = df_ts_complex.index.dayofweek
df_ts_complex['day_of_month'] = df_ts_complex.index.day
df_ts_complex['month'] = df_ts_complex.index.month
df_ts_complex['quarter'] = df_ts_complex.index.quarter

# 4. 创建周期性特征
df_ts_complex['sin_day'] = np.sin(2 * np.pi * df_ts_complex.index.dayofyear / 365)
df_ts_complex['cos_day'] = np.cos(2 * np.pi * df_ts_complex.index.dayofyear / 365)

# 5. 创建节假日特征(示例)
holidays = pd.to_datetime(['2020-01-01', '2020-02-01', '2020-05-01', 
                          '2020-10-01', '2020-12-25'])
df_ts_complex['is_holiday'] = df_ts_complex.index.isin(holidays).astype(int)

print("\n特征工程后的数据:")
print(df_ts_complex.head())

7.3 机器学习模型预测

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, r2_score

# 准备数据
df_ts_complex = df_ts_complex.dropna()  # 删除包含NaN的行

# 特征和目标
X = df_ts_complex.drop('销售额', axis=1)
y = df_ts_complex['销售额']

# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

print(f"训练集大小:{X_train.shape[0]}")
print(f"测试集大小:{X_test.shape[0]}")

# 训练随机森林模型
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)

# 预测
y_pred = rf_model.predict(X_test)

# 评估
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"\n模型评估:")
print(f"平均绝对误差(MAE):{mae:.2f}")
print(f"R²分数:{r2:.4f}")

# 特征重要性
feature_importance = pd.DataFrame({
    '特征': X.columns,
    '重要性': rf_model.feature_importances_
}).sort_values('重要性', ascending=False)

print("\n特征重要性:")
print(feature_importance.head(10))

# 可视化预测结果
plt.figure(figsize=(12, 6))
plt.plot(y_test.index, y_test, label='真实值', alpha=0.7)
plt.plot(y_test.index, y_pred, label='预测值', alpha=0.7, color='red')
plt.title('随机森林模型预测结果')
plt.legend()
plt.show()

第八部分:总结与进阶学习路径

8.1 课程总结

通过本课程的学习,你已经掌握了:

  1. Pandas高级操作:多级索引、高效分组、数据合并
  2. 高级数据清洗:缺失值处理、异常值检测与处理
  3. 高级可视化:Seaborn统计可视化、Plotly交互式可视化
  4. 时间序列分析:重采样、滚动窗口、季节性分解、预测
  5. 实战项目:电商销售数据分析、RFM客户分析
  6. 性能优化:内存优化、向量化操作、大数据处理
  7. 机器学习预测:特征工程、随机森林预测模型

8.2 进阶学习路径

1. 深度学习与时间序列

  • 学习LSTM、GRU等循环神经网络
  • 使用TensorFlow或PyTorch进行时间序列预测
  • 探索Transformer在时间序列中的应用

2. 大数据处理框架

  • 深入学习Spark和PySpark
  • 掌握Dask的高级用法
  • 了解分布式计算原理

3. 高级可视化与仪表板

  • 学习Dash或Streamlit创建交互式Web应用
  • 掌握Tableau或Power BI集成
  • 学习地理空间可视化(GeoPandas, Folium)

4. 统计分析与因果推断

  • 学习统计假设检验
  • 掌握因果推断方法(双重差分、断点回归等)
  • 学习贝叶斯统计方法

5. 生产环境部署

  • 学习模型部署(Flask, FastAPI)
  • 了解MLOps基础
  • 学习数据管道构建(Airflow, Prefect)

8.3 推荐资源

  1. 书籍

    • 《Python for Data Analysis》(Wes McKinney)
    • 《Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow》
    • 《Forecasting: Principles and Practice》
  2. 在线课程

    • Coursera: “Applied Data Science with Python”
    • edX: “Data Science MicroMasters”
    • Kaggle Learn: 数据科学课程
  3. 实践平台

    • Kaggle:参与数据科学竞赛
    • GitHub:贡献开源项目
    • DataCamp:交互式学习
  4. 社区与论坛

    • Stack Overflow
    • Reddit的r/datascience
    • Python数据分析社区

8.4 最终建议

  1. 持续实践:数据分析是实践性很强的技能,多做项目
  2. 关注领域知识:结合具体业务场景学习
  3. 保持学习:技术发展迅速,持续更新知识
  4. 建立作品集:将项目整理到GitHub,展示能力
  5. 参与社区:与同行交流,获取反馈

通过本课程的系统学习,你已经具备了从基础到实战的Python数据分析能力。记住,数据分析的终极目标是解决实际问题,创造业务价值。祝你在数据分析的道路上不断进步!


课程结束