本文目录导读:

我来为你介绍如何用Pandas实现数据分组日历的多个实用案例:
案例1:基础日历年月分组统计
import pandas as pd
import numpy as np
from datetime import datetime
# 创建示例数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', '2023-12-31', freq='H')
data = pd.DataFrame({
'日期': dates,
'销售额': np.random.randint(100, 1000, len(dates)),
'用户数': np.random.randint(10, 100, len(dates))
})
# 提取年月信息
data['年'] = data['日期'].dt.year
data['月'] = data['日期'].dt.month
data['年-月'] = data['日期'].dt.strftime('%Y-%m')
# 按月分组统计
monthly_stats = data.groupby('年-月').agg({
'销售额': ['sum', 'mean', 'max'],
'用户数': ['sum', 'mean']
}).round(2)
print("月度统计:")
print(monthly_stats.head())
案例2:按周和季度分组
# 设置日期为索引
data.set_index('日期', inplace=True)
# 按周分组
weekly_stats = data.resample('W').agg({
'销售额': ['sum', 'mean'],
'用户数': 'sum'
})
print("\n周度统计(前5周):")
print(weekly_stats.head())
# 按季度分组
quarterly_stats = data.resample('Q').agg({
'销售额': ['sum', 'mean', 'std'],
'用户数': ['sum', 'mean']
}).round(2)
print("\n季度统计:")
print(quarterly_stats)
案例3:工作日与周末分析
# 创建包含工作日信息的数据
data['星期几'] = data.index.dayofweek
data['是否工作日'] = data['星期几'].apply(lambda x: '工作日' if x < 5 else '周末')
# 按工作日/周末分组
workday_stats = data.groupby('是否工作日').agg({
'销售额': ['sum', 'mean', 'count'],
'用户数': ['sum', 'mean']
}).round(2)
print("\n工作日 vs 周末统计:")
print(workday_stats)
# 按星期几分组
weekday_stats = data.groupby('星期几').agg({
'销售额': ['sum', 'mean'],
'用户数': 'sum'
})
# 重命名星期索引
weekday_names = {0: '周一', 1: '周二', 2: '周三', 3: '周四',
4: '周五', 5: '周六', 6: '周日'}
weekday_stats.index = weekday_stats.index.map(weekday_names)
print("\n每周各天统计:")
print(weekday_stats)
案例4:复杂日历统计(包含节假日)
# 添加节假日信息
holidays_2023 = pd.to_datetime([
'2023-01-01', # 元旦
'2023-01-22', # 春节
'2023-04-05', # 清明节
'2023-05-01', # 劳动节
'2023-06-22', # 端午节
'2023-10-01', # 国庆节
])
data['是否节假日'] = data.index.isin(holidays_2023)
data['日期类型'] = data.apply(lambda row:
'节假日' if row['是否节假日']
else ('周末' if row['星期几'] >= 5 else '工作日'),
axis=1
)
# 按日期类型分组统计
date_type_stats = data.groupby('日期类型').agg({
'销售额': ['sum', 'mean', 'count'],
'用户数': ['sum', 'mean']
}).round(2)
print("\n按日期类型统计:")
print(date_type_stats)
案例5:自定义日历统计函数
def calendar_summary(df, date_col='日期', value_cols=['销售额', '用户数']):
"""
生成完整的日历统计摘要
参数:
- df: DataFrame
- date_col: 日期列名
- value_cols: 需要统计的数值列列表
"""
df = df.copy()
df['日期'] = pd.to_datetime(df[date_col])
# 提取各种时间维度
df['年'] = df['日期'].dt.year
df['月'] = df['日期'].dt.month
df['周'] = df['日期'].dt.isocalendar().week
df['季度'] = df['日期'].dt.quarter
df['星期几'] = df['日期'].dt.dayofweek
df['周几名称'] = df['星期几'].map({
0: '周一', 1: '周二', 2: '周三', 3: '周四',
4: '周五', 5: '周六', 6: '周日'
})
# 生成多种分组统计
summaries = {}
# 1. 年月统计
summaries['year_month'] = df.groupby(['年', '月'])[value_cols].sum()
# 2. 季度统计
summaries['quarterly'] = df.groupby(['年', '季度'])[value_cols].agg(['sum', 'mean'])
# 3. 周统计
summaries['weekly'] = df.groupby(['年', '周'])[value_cols].sum()
# 4. 星期统计
summaries['weekday'] = df.groupby('周几名称')[value_cols].mean()
return summaries
# 使用自定义函数
summaries = calendar_summary(data.reset_index())
print("年月统计:")
print(summaries['year_month'].head(6))
print("\n平均星期统计:")
print(summaries['weekday'])
案例6:可视化日历统计
import matplotlib.pyplot as plt
# 准备数据
data['日期'] = data.index
daily_sales = data.groupby('日期')['销售额'].sum().reset_index()
# 创建日历热力图
def plot_calendar_heatmap(df, date_col, value_col, year=2023):
"""绘制日历热力图"""
# 筛选指定年份
df_year = df[pd.to_datetime(df[date_col]).dt.year == year].copy()
df_year['日期'] = pd.to_datetime(df_year[date_col])
df_year['月'] = df_year['日期'].dt.month
df_year['日'] = df_year['日期'].dt.day
df_year['周几'] = df_year['日期'].dt.dayofweek
# 创建透视表
pivot = df_year.pivot_table(
values=value_col,
index='周几',
columns='月',
aggfunc='sum',
fill_value=0
)
# 绘制热力图
fig, ax = plt.subplots(figsize=(12, 6))
im = ax.imshow(pivot.values, cmap='YlOrRd', aspect='auto')
# 设置标签
ax.set_xticks(range(12))
ax.set_xticklabels(['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月'])
ax.set_yticks(range(7))
ax.set_yticklabels(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
plt.colorbar(im, label='销售额')
plt.title(f'{year}年日历销售热力图')
plt.tight_layout()
return fig
# 绘制热力图
fig = plot_calendar_heatmap(daily_sales, '日期', '销售额')
plt.show()
案例7:实际业务场景 - 销售分析
# 创建更真实的销售数据
np.random.seed(42)
sales_data = pd.DataFrame({
'订单日期': pd.date_range('2023-01-01', '2023-12-31', freq='D'),
'产品类别': np.random.choice(['电子产品', '服装', '食品', '家居'], 365),
'销售额': np.random.randint(100, 5000, 365),
'订单数量': np.random.randint(1, 20, 365),
'客户ID': np.random.randint(1000, 2000, 365)
})
# 添加时间维度
sales_data['月份'] = pd.to_datetime(sales_data['订单日期']).dt.month
sales_data['季度'] = pd.to_datetime(sales_data['订单日期']).dt.quarter
sales_data['星期'] = pd.to_datetime(sales_data['订单日期']).dt.day_name()
# 1. 按月份和产品类别分析
monthly_category = sales_data.groupby(['月份', '产品类别']).agg({
'销售额': 'sum',
'订单数量': 'sum',
'客户ID': pd.Series.nunique
}).round(2)
print("月度-产品类别分析:")
print(monthly_category.head(12))
# 2. 按季度和星期分析
quarterly_weekday = sales_data.groupby(['季度', '星期']).agg({
'销售额': ['sum', 'mean', 'count'],
'订单数量': 'sum'
}).round(2)
print("\n季度-星期分析:")
print(quarterly_weekday)
# 3. 交叉分析
cross_analysis = pd.crosstab(
sales_data['季度'],
sales_data['产品类别'],
values=sales_data['销售额'],
aggfunc='sum'
).round(2)
print("\n季度-产品类别交叉分析:")
print(cross_analysis)
# 1. 快速查看数据的时间范围
print(f"数据时间范围:{data.index.min()} 到 {data.index.max()}")
# 2. 统计每天的记录数
daily_counts = data.resample('D').size()
print(f"平均每天记录数:{daily_counts.mean():.0f}")
# 3. 找出销售最高的日期
max_sales_date = data.groupby(data.index.date)['销售额'].sum().idxmax()
print(f"销售最高日期:{max_sales_date}")
# 4. 计算同比环比
monthly_sales = data.resample('M')['销售额'].sum()
yoy_growth = monthly_sales.pct_change(periods=12) * 100
mom_growth = monthly_sales.pct_change() * 100
# 5. 创建日期维度表
date_dim = pd.DataFrame({
'日期': pd.date_range('2023-01-01', '2023-12-31'),
'年': range(2023, 2024),
'月': range(1, 13),
'日': range(1, 32)
})
这些案例涵盖了从基础到高级的数据分组日历分析技巧,可以根据实际业务需求灵活运用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播