pydata-book高级数据分析技巧深度剖析

pydata-book高级数据分析技巧深度剖析

本文深度剖析了pydata-book中关于数据聚合分组、时间序列分析、数据可视化及建模库集成等高级数据分析技巧。文章通过丰富的代码示例和实战案例,详细介绍了使用pandas进行高效数据分组统计、时间序列处理、matplotlib和seaborn可视化,以及statsmodels和scikit-learn建模集成的完整流程,为读者提供了从数据处理到模型部署的全面指导。

数据聚合与分组操作实战

在数据分析的实际应用中,数据聚合与分组操作是最核心且最常用的技术之一。通过pandas强大的groupby功能,我们可以轻松地对数据进行分组统计、聚合计算和复杂的数据转换。本章将深入探讨数据聚合与分组操作的各种实战技巧,帮助您掌握这一关键数据分析技能。

基础分组操作

让我们从最基本的分组操作开始。假设我们有一个包含餐厅小费数据的DataFrame:

import pandas as pd
import numpy as np

# 读取小费数据集
tips = pd.read_csv('examples/tips.csv')
print(tips.head())
total_billtipsmokerdaytimesize
16.991.01NoSunDinner2
10.341.66NoSunDinner3
21.013.5NoSunDinner3
23.683.31NoSunDinner2
24.593.61NoSunDinner4

mermaid

单列分组与聚合

最基本的groupby操作是按单个列进行分组并计算聚合统计量:

# 按吸烟状态分组,计算小费的平均值
tips_grouped = tips.groupby('smoker')['tip'].mean()
print(tips_grouped)
smoker
No     2.991854
Yes    3.008710
Name: tip, dtype: float64

多列分组操作

在实际分析中,我们经常需要按多个维度进行分组:

# 按日期和吸烟状态进行分组
grouped_multiple = tips.groupby(['day', 'smoker'])
result = grouped_multiple['total_bill'].agg(['mean', 'std', 'count'])
print(result)
daysmokermeanstdcount
FriNo18.424.154
FriYes16.813.7615
SatNo19.668.3345
SatYes21.288.9842
SunNo20.519.2557
SunYes24.129.6819
ThurNo17.113.9145
ThurYes19.194.7917

自定义聚合函数

除了内置的聚合函数,我们还可以使用自定义函数:

# 定义自定义聚合函数:极差(最大值-最小值)
def peak_to_peak(arr):
    return arr.max() - arr.min()

# 应用自定义聚合函数
custom_agg = tips.groupby('day')['total_bill'].agg(peak_to_peak)
print(custom_agg)
day
Fri     34.65
Sat     48.27
Sun     47.74
Thur    35.83
Name: total_bill, dtype: float64

多函数聚合

我们可以同时对多个列应用多个聚合函数:

# 对多个列应用多个聚合函数
multi_agg = tips.groupby(['day', 'smoker']).agg({
    'total_bill': ['mean', 'max', 'min'],
    'tip': ['mean', 'std'],
    'size': 'sum'
})
print(multi_agg)

分组后的数据转换

groupby不仅用于聚合,还可以进行数据转换:

# 计算每个组内的小费百分比
tips['tip_pct'] = tips['tip'] / tips['total_bill']

# 按日期分组并标准化小费百分比
def standardize(group):
    return (group - group.mean()) / group.std()

standardized = tips.groupby('day')['tip_pct'].transform(standardize)
tips['tip_pct_standardized'] = standardized

分组筛选操作

我们可以基于分组统计结果来筛选数据:

# 筛选出小费百分比高于组平均值的记录
def filter_high_tippers(group):
    return group[group['tip_pct'] > group['tip_pct'].mean()]

high_tippers = tips.groupby('day').apply(filter_high_tippers)
print(high_tippers.head())

时间序列分组

对于时间序列数据,我们可以使用重采样进行分组:

# 创建示例时间序列数据
date_range = pd.date_range('2023-01-01', periods=100, freq='D')
time_series = pd.DataFrame({
    'value': np.random.randn(100).cumsum(),
    'category': np.random.choice(['A', 'B', 'C'], 100)
}, index=date_range)

# 按月份和类别分组
monthly_grouped = time_series.groupby([
    pd.Grouper(freq='M'), 
    'category'
])['value'].mean()

高级分组技巧

# 使用字典进行列分组
column_mapping = {'total_bill': 'amount', 'tip': 'amount', 'size': 'count'}
column_grouped = tips.groupby(column_mapping, axis=1).sum()

# 使用函数进行分组
def time_of_day(time_str):
    if time_str == 'Lunch':
        return 'Day'
    else:
        return 'Night'

time_grouped = tips.groupby(time_of_day)['total_bill'].mean()

性能优化技巧

对于大数据集,分组操作可能需要优化:

# 使用categorical类型优化分组性能
tips['day'] = tips['day'].astype('category')
tips['smoker'] = tips['smoker'].astype('category')

# 使用numba加速自定义函数
import numba

@numba.jit
def fast_peak_to_peak(arr):
    return arr.max() - arr.min()

# 应用优化后的函数
optimized_result = tips.groupby('day')['total_bill'].agg(fast_peak_to_peak)

实战案例:餐厅数据分析

让我们通过一个完整的案例来展示分组操作的强大功能:

# 综合分组分析
analysis_result = tips.groupby(['day', 'time', 'smoker']).agg({
    'total_bill': ['count', 'mean', 'std', 'min', 'max'],
    'tip': ['mean', 'median', lambda x: x.quantile(0.75)],
    'size': ['mean', 'sum']
}).round(2)

# 重命名列
analysis_result.columns = [
    '订单数', '平均消费', '消费标准差', '最低消费', '最高消费',
    '平均小费', '小费中位数', '小费75分位数',
    '平均人数', '总人数'
]

print(analysis_result)

通过掌握这些数据聚合与分组操作技巧,您将能够高效地进行复杂的数据分析任务,从简单的统计汇总到高级的数据转换,都能游刃有余。记住,熟练运用groupby是成为数据分析高手的必经之路。

时间序列数据分析方法

时间序列数据分析是数据科学中至关重要的技能,特别是在金融、物联网、商业智能等领域。pydata-book项目通过第11章全面展示了如何使用pandas进行高效的时间序列处理,涵盖了从基础操作到高级分析的完整流程。

时间序列基础操作

时间序列数据的核心在于索引的处理。pandas提供了强大的时间索引功能,能够轻松处理各种时间频率的数据:

import pandas as pd
import numpy as np
from datetime import datetime

# 创建基础时间序列
dates = [datetime(2011, 1, 2), datetime(2011, 1, 5), datetime(2011, 1, 7)]
ts = pd.Series(np.random.standard_normal(3), index=dates)
print(ts)

输出结果:

2011-01-02   -0.1724
2011-01-05    0.7658
2011-01-07   -0.0037
dtype: float64

时间索引的切片与选择

pandas的时间索引支持灵活的切片操作,可以按年、月、日等不同粒度进行数据选择:

# 创建长时间序列
longer_ts = pd.Series(np.random.standard_normal(1000),
                      index=pd.date_range("2000-01-01", periods=1000))

# 按年份选择
year_2001 = longer_ts["2001"]
print(f"2001年数据长度: {len(year_2001)}")

# 按年月选择
may_2001 = longer_ts["2001-05"]
print(f"2001年5月数据长度: {len(may_2001)}")

重采样与频率转换

重采样是时间序列分析中的核心技术,可以将数据从一种频率转换为另一种频率:

mermaid

# 日数据重采样为月数据
monthly_data = ts.resample("M").mean()
print("月度重采样结果:")
print(monthly_data)

# 使用不同聚合方法
monthly_sum = ts.resample("M").sum()
monthly_count = ts.resample("M").count()

移动窗口操作

移动窗口统计是时间序列分析的重要技术,用于计算滚动平均值、标准差等:

# 创建示例金融时间序列
close_px = pd.DataFrame({
    'AAPL': np.random.randn(1000).cumsum() + 100,
    'MSFT': np.random.randn(1000).cumsum() + 50
}, index=pd.date_range('2000-01-01', periods=1000))

# 计算250日移动平均
rolling_mean = close_px['AAPL'].rolling(250).mean()
print("250日移动平均值前5个:")
print(rolling_mean.head())

# 计算滚动标准差
rolling_std = close_px['AAPL'].pct_change().rolling(250, min_periods=10).std()

时间序列数据清洗

处理时间序列数据时经常遇到缺失值和不规则频率的问题:

# 处理缺失值
frame = pd.DataFrame(np.random.standard_normal((365, 4)),
                     index=pd.date_range('2000-01-01', periods=365),
                     columns=['A', 'B', 'C', 'D'])

# 前向填充缺失值
filled_frame = frame.resample("D").ffill(limit=2)
print("前向填充后的数据形状:", filled_frame.shape)

# 使用不同填充策略
asfreq_result = frame.resample("D").asfreq()

高级时间序列操作

pandas支持更复杂的时间序列操作,包括时间偏移、周期转换等:

# 时间偏移操作
ts_shifted = ts.shift(2)  # 向后移动2个周期
ts_shifted_negative = ts.shift(-2)  # 向前移动2个周期

# 带频率的时间偏移
ts_shifted_freq = ts.shift(2, freq="M")  # 移动2个月

# 周期索引转换
period_index = ts.resample("M", kind="period").mean()

实际应用案例

以下是一个完整的时间序列分析流程示例:

# 1. 数据准备
dates = pd.date_range('2020-01-01', periods=500, freq='D')
data = pd.Series(np.random.randn(500).cumsum(), index=dates)

# 2. 重采样为周数据
weekly_data = data.resample('W').mean()

# 3. 计算移动平均
ma_30 = data.rolling(30).mean()
ma_90 = data.rolling(90).mean()

# 4. 计算收益率
returns = data.pct_change()

# 5. 波动率分析
volatility = returns.rolling(30).std() * np.sqrt(252)  # 年化波动率

性能优化技巧

处理大规模时间序列数据时,性能优化至关重要:

优化技巧描述效果
使用pd.to_datetime()批量转换时间字符串大幅提升转换速度
避免重复重采样预处理数据时一次性完成减少计算开销
使用inplace=True原地操作减少内存使用节省内存空间
选择合适的频率根据分析需求选择适当频率平衡精度与性能
# 高效的时间序列处理示例
# 批量转换时间字符串
date_strings = ['2020-01-01', '2020-01-02', '2020-01-03']
efficient_dates = pd.to_datetime(date_strings)

# 使用合适的数据类型
ts = ts.astype('float32')  # 减少内存使用

时间序列数据分析是一个深度和广度都很丰富的领域,pydata-book通过实际案例和代码示例,为学习者提供了从基础到高级的完整学习路径。掌握这些技能后,你将能够处理各种复杂的时间序列分析任务,为数据驱动的决策提供有力支持。

数据可视化与图表生成

在数据分析的完整流程中,数据可视化是至关重要的一环。pydata-book项目通过matplotlib、pandas内置绘图功能以及seaborn等库,展示了丰富的数据可视化技术。本章将深入探讨这些工具的使用方法和最佳实践。

matplotlib基础绘图

matplotlib是Python中最基础且功能强大的绘图库,提供了从简单线图到复杂子图布局的完整解决方案。

import matplotlib.pyplot as plt
import numpy as np

# 创建基础线图
data = np.arange(10)
plt.plot(data)
plt.title('基础线图示例')
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.show()

matplotlib的核心概念包括Figure(画布)、Axes(坐标系)和Artist(图形元素)。通过组合这些组件,可以创建复杂的多子图布局:

# 创建2x2子图布局
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# 在每个子图中绘制不同类型的图表
axes[0, 0].hist(np.random.standard_normal(100), bins=20, color='black', alpha=0.3)
axes[0, 1].scatter(np.arange(30), np.arange(30) + 3 * np.random.standard_normal(30))
axes[1, 0].plot(np.random.standard_normal(50).cumsum(), color='black', linestyle='dashed')
axes[1, 1].bar(['A', 'B', 'C', 'D'], [10, 20, 15, 25])

plt.tight_layout()
plt.show()

pandas内置绘图功能

pandas库为DataFrame和Series对象提供了便捷的绘图方法,大大简化了常见图表的创建过程。

import pandas as pd
import numpy as np

# 创建示例数据
s = pd.Series(np.random.standard_normal(10).cumsum(), index=np.arange(0, 100, 10))
df = pd.DataFrame({
    'A': np.random.randn(100),
    'B': np.random.randn(100),
    'C': np.random.randn(100)
})

# Series绘图
s.plot(title='Series线图', grid=True)

# DataFrame多列绘图
df.plot(alpha=0.5, figsize=(12, 6))

pandas支持多种图表类型,通过kind参数指定:

图表类型kind参数适用场景
线图'line'时间序列数据趋势分析
柱状图'bar'分类数据比较
水平柱状图'barh'长类别名称的显示
直方图'hist'数据分布分析
箱线图'box'数据统计特征展示
面积图'area'累积效应展示
散点图'scatter'变量关系分析
饼图'pie'比例分布展示

高级图表定制

matplotlib提供了丰富的定制选项,可以精确控制图表的每个细节:

fig, ax = plt.subplots(figsize=(12, 6))

# 绘制多条线并添加样式
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), color='blue', linestyle='-', linewidth=2, label='sin(x)')
ax.plot(x, np.cos(x), color='red', linestyle='--', linewidth=2, label='cos(x)')

# 设置坐标轴和标题
ax.set_xlabel('X轴', fontsize=12)
ax.set_ylabel('Y轴', fontsize=12)
ax.set_title('三角函数图像', fontsize=14)

# 添加网格和图例
ax.grid(True, alpha=0.3)
ax

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值