Python案例如何用Pandas做数据分组重采伸缩

wen python案例 7

本文目录导读:

Python案例如何用Pandas做数据分组重采伸缩

  1. 基础准备
  2. 时间序列重采样
  3. 分组重采样
  4. 数据伸缩(Scaling)
  5. 实用案例
  6. 高级技巧
  7. 数据导出与保存
  8. 总结要点

我来详细讲解如何使用 Pandas 进行数据分组重采样(resampling)和伸缩(scaling)操作。

基础准备

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 创建示例数据
np.random.seed(42)
# 生成时间序列数据
dates = pd.date_range('2024-01-01', periods=100, freq='D')
df = pd.DataFrame({
    'date': dates,
    'sales': np.random.randint(100, 500, 100),
    'category': np.random.choice(['A', 'B', 'C'], 100),
    'price': np.random.uniform(10, 50, 100).round(2)
})
print("原始数据预览:")
print(df.head())
print(f"\n数据形状: {df.shape}")

时间序列重采样

1 基本重采样

# 设置日期为索引
df_time = df.set_index('date')
# 按周重采样
weekly_data = df_time['sales'].resample('W').sum()
print("按周汇总:")
print(weekly_data.head())
# 按月重采样
monthly_data = df_time['sales'].resample('M').mean()
print("\n按月平均值:")
print(monthly_data.head())
# 按季度重采样
quarterly_data = df_time['sales'].resample('Q').agg(['sum', 'mean', 'std'])
print("\n按季度统计:")
print(quarterly_data.head())

2 不同的聚合函数

# 多种聚合方式
resampled_df = df_time.resample('W').agg({
    'sales': ['sum', 'mean', 'max', 'min'],
    'price': ['mean', 'std']
})
print("多列多函数重采样:")
print(resampled_df.head())

分组重采样

1 按类别分组后重采样

# 按类别和时间分组重采样
df_grouped = df.set_index('date')
# 按类别分组后按月重采样
category_monthly = df_grouped.groupby('category').resample('M')['sales'].agg(['sum', 'mean'])
print("按类别和月份分组:")
print(category_monthly.head(10))
# 更复杂的聚合
pivoted_data = df_grouped.groupby('category').resample('W').agg({
    'sales': 'sum',
    'price': 'mean'
}).round(2)
print("\n按类别和周的统计:")
print(pivoted_data.head(10))

2 多级分组重采样

# 添加更多分组维度
df['region'] = np.random.choice(['North', 'South', 'East', 'West'], 100)
# 多级分组重采样
multi_grouped = df.set_index('date').groupby(['category', 'region']).resample('M')['sales'].sum()
print("多级分组重采样:")
print(multi_grouped.head(10))

数据伸缩(Scaling)

1 归一化(Min-Max Scaling)

from sklearn.preprocessing import MinMaxScaler, StandardScaler
# Min-Max 归一化
def min_max_scaling(group):
    scaler = MinMaxScaler()
    group['sales_scaled'] = scaler.fit_transform(group[['sales']])
    return group
# 按类别分组后归一化
df_scaled = df.groupby('category').apply(min_max_scaling)
print("Min-Max 归一化结果:")
print(df_scaled[df_scaled['category'] == 'A'].head())

2 标准化(Z-score Scaling)

# 标准化
def standard_scaling(group):
    scaler = StandardScaler()
    group['sales_standardized'] = scaler.fit_transform(group[['sales']])
    group['price_standardized'] = scaler.fit_transform(group[['price']])
    return group
# 按类别分组后标准化
df_standardized = df.groupby('category').apply(standard_scaling)
print("\n标准化结果:")
print(df_standardized[df_standardized['category'] == 'B'].head())

实用案例

案例1:销售数据分析

# 创建销售数据
sales_data = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=365, freq='D'),
    'product': np.random.choice(['Product_A', 'Product_B', 'Product_C'], 365),
    'sales_amount': np.random.uniform(1000, 5000, 365).round(2),
    'units_sold': np.random.randint(10, 100, 365)
})
# 按月分析每个产品的销售趋势
monthly_trend = (sales_data.set_index('date')
                .groupby('product')
                .resample('M')
                .agg({
                    'sales_amount': 'sum',
                    'units_sold': 'sum'
                }))
print("月度销售趋势:")
print(monthly_trend.head(10))
# 计算每个产品的月度增长率
for product in monthly_trend.index.get_level_values(0).unique():
    product_data = monthly_trend.loc[product]
    product_data['growth_rate'] = product_data['sales_amount'].pct_change() * 100
    print(f"\n{product} 月度增长率:")
    print(product_data[['sales_amount', 'growth_rate']].head())

案例2:股票数据分析

# 模拟股票数据
stock_data = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=100, freq='D'),
    'stock': np.random.choice(['AAPL', 'GOOGL', 'MSFT'], 100),
    'price': np.random.uniform(150, 200, 100).round(2),
    'volume': np.random.randint(1000000, 5000000, 100)
})
# 按周分析股票
weekly_stock = (stock_data.set_index('date')
               .groupby('stock')
               .resample('W')
               .agg({
                   'price': ['first', 'last', 'min', 'max', 'mean'],
                   'volume': 'sum'
               }))
print("周度股票分析:")
print(weekly_stock.head(10))
# 计算每周收益率
def calculate_weekly_return(group):
    weekly_return = (group['price'].resample('W').last() / 
                    group['price'].resample('W').first() - 1) * 100
    return weekly_return
stock_returns = stock_data.set_index('date').groupby('stock').apply(calculate_weekly_return)
print("\n每周收益率:")
print(stock_returns.head())

高级技巧

1 自定义聚合函数

def custom_agg(group):
    """自定义聚合函数"""
    return pd.Series({
        'mean': group.mean(),
        'median': group.median(),
        'iqr': group.quantile(0.75) - group.quantile(0.25),
        'cv': group.std() / group.mean() * 100  # 变异系数
    })
# 应用自定义函数
custom_results = (df.set_index('date')
                 .groupby('category')
                 .resample('M')
                 .apply(custom_agg))
print("自定义聚合结果:")
print(custom_results.head())

2 滚动窗口分析

# 滚动窗口计算
rolling_stats = (df.set_index('date')
                .groupby('category')['sales']
                .rolling(window=7)
                .agg(['mean', 'std', 'min', 'max']))
print("7天滚动统计:")
print(rolling_stats.head(10))
# 绘制滚动平均
category_a = df[df['category'] == 'A'].set_index('date')['sales']
category_a_rolling = category_a.rolling(window=7).mean()
plt.figure(figsize=(12, 6))
plt.plot(category_a.index, category_a.values, label='原始数据', alpha=0.5)
plt.plot(category_a_rolling.index, category_a_rolling.values, label='7天滚动平均')'类别A的销售额趋势')
plt.xlabel('日期')
plt.ylabel('销售额')
plt.legend()
plt.show()

数据导出与保存

# 保存处理后的数据
def save_processed_data(df, filename):
    """保存处理后的数据"""
    df.to_csv(filename, index=True)
    print(f"数据已保存到 {filename}")
# 保存不同维度的分析结果
save_processed_data(weekly_data, 'weekly_sales.csv')
save_processed_data(monthly_trend, 'monthly_trend.csv')
save_processed_data(weekly_stock, 'weekly_stock_analysis.csv')
# 也可以保存为Excel格式(多表)
with pd.ExcelWriter('analysis_report.xlsx') as writer:
    weekly_data.to_excel(writer, sheet_name='周度销售')
    monthly_trend.to_excel(writer, sheet_name='月度趋势')
    weekly_stock.to_excel(writer, sheet_name='股票分析')

总结要点

  1. 重采样频率:'D'(天)、'W'(周)、'M'(月)、'Q'(季度)、'Y'(年)
  2. 聚合函数:sum、mean、std、min、max、first、last
  3. 分组维度:按类别、地区等多维度组合
  4. 数据伸缩:归一化、标准化等预处理方法
  5. 窗口函数:滚动计算、移动平均等时间序列分析

这些技巧可以帮助你更有效地处理时间序列数据,进行深入的数据分析和洞察。

抱歉,评论功能暂时关闭!