3、Python量化工具栈:Pandas数据处理、NumPy数值计算、Matplotlib/Plotly可视化、Statsmodels统计分析
说实话,刚入行那会儿,我总觉得工具就是工具,会用就行。直到有一次做原油裂解价差模型,数据量一上来,Excel直接崩了,我才意识到——在能源化工这个数据密集型行业,选对工具栈,比埋头苦干重要得多。
今天咱们就聊聊Python量化分析的四驾马车。它们各有各的脾气,但组合起来,就是一套完整的产业链分析流水线。
3.1 NumPy:数值计算的基石
NumPy,说白了就是Python里的数学引擎。我习惯叫它“数组工厂”。
为什么非得用它?因为Python原生的列表做数学运算,慢得让人抓狂。你想想看,处理一套炼厂三年的日度开工率数据,少说也得一千多个点。用列表循环算个标准差?嗯,等得你都能泡杯茶了。
核心数据结构:ndarray
ndarray就是NumPy的多维数组。跟列表最大的区别是——它所有元素类型必须一致。这听起来是限制,其实是优势。类型统一后,内存连续,计算速度能快几十倍。
import numpy as np
# 创建一个原油价格数组(单位:美元/桶)
crude_prices = np.array([72.5, 73.1, 71.8, 74.2, 73.9])
print(crude_prices.dtype) # float64
# 批量运算——这才是NumPy的杀手锏
# 计算日收益率
daily_returns = (crude_prices[1:] - crude_prices[:-1]) / crude_prices[:-1]
print(daily_returns)
# 输出: [ 0.0083 -0.0178 0.0334 -0.0040]
我的小技巧:做能源化工数据时,我经常用 np.where() 做条件筛选。比如找出所有价格超过布林带上轨的日期,一行代码搞定,比写循环清爽多了。
3.2 Pandas:表格数据的瑞士军刀
NumPy处理的是“裸数据”,而Pandas给数据穿上了衣服——行索引、列标签、时间序列,全给你安排得明明白白。
我个人觉得,Pandas最牛的地方是DataFrame。它就像Excel表格,但比Excel灵活一万倍。我在做PX-石脑油价差分析时,经常要合并不同来源的数据——中石化的报价、普氏的评估、ICE的期货价格。用Pandas的merge()和concat(),几分钟就能搞定。
import pandas as pd
# 读取某炼厂的月度产量数据(假设是CSV格式)
df = pd.read_csv('refinery_production.csv', parse_dates=['date'])
df.set_index('date', inplace=True)
# 计算滚动均值——做技术指标必备
df['MA_30'] = df['crude_throughput'].rolling(window=30).mean()
# 缺失值处理——真实数据永远不完美
df['yield_gasoline'].fillna(method='ffill', inplace=True) # 前向填充
# 我曾经踩过的坑:直接用dropna()会丢掉大量有效数据
# 对于化工装置数据,我更推荐用插值法
注意:Pandas的inplace=True参数,很多人喜欢用。但我建议你谨慎——它直接修改原数据,一旦出错很难回溯。我现在的习惯是:除非内存实在不够,否则都返回新DataFrame。
3.3 Matplotlib & Plotly:让数据说话
数据算完了,不画出来等于白干。你想想看,给老板汇报时,你甩出一堆数字,他肯定一脸懵。但一张图,胜过千言万语。
Matplotlib是静态图的王者,适合做论文、报告里的精美图表。Plotly则是交互式图表的好手,适合做数据探索和Dashboard。
import matplotlib.pyplot as plt
import plotly.express as px
# Matplotlib:画一条原油价格曲线
plt.figure(figsize=(10, 5))
plt.plot(df.index, df['crude_price'], label='WTI Crude', color='#2E86AB')
plt.title('原油价格走势(2023-2024)')
plt.xlabel('日期')
plt.ylabel('美元/桶')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# Plotly:交互式散点图——鼠标悬停就能看数据
fig = px.scatter(df, x='crude_price', y='gasoline_price',
hover_data=['date'],
title='原油与汽油价格相关性')
fig.show()
我的配色习惯:能源化工行业,我常用蓝色系(原油)、橙色系(成品油)、绿色系(化工品)。这样看图的人一眼就能区分品种。别用花里胡哨的颜色,专业感很重要。
3.4 Statsmodels:统计建模的利器
前面三个工具帮我们“看清”数据,而Statsmodels帮我们“解释”数据。它内置了各种统计模型——线性回归、时间序列分析、假设检验等等。
做能源化工量化,我最常用的是ARIMA模型和协整检验。比如判断石脑油和丙烷之间是否存在套利机会,协整检验就是关键。
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
# 对某化工品价格序列做平稳性检验
result = adfuller(df['propylene_price'].dropna())
print(f'ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
if result[1] < 0.05:
print('序列平稳,可以直接建模')
else:
print('序列非平稳,需要差分处理')
# 线性回归:分析原油价格对石脑油价格的影响
X = sm.add_constant(df['crude_price'])
y = df['naphtha_price']
model = sm.OLS(y, X).fit()
print(model.summary()) # 看R-squared和p-value
避坑指南:我曾经在分析PTA加工利润时,直接用原始数据跑回归,结果R²高达0.95,兴奋得不行。后来发现——两个序列都是非平稳的,这是伪回归!记住:非平稳序列之间做回归,必须先检验协整关系。
3.5 四者协同:一个完整的分析流程
光讲单个工具没意思,咱们串起来看看。假设我要分析“原油→石脑油→PX→PTA”这条产业链的利润传导机制:
- NumPy:计算各环节的加工利润(价差),做标准化处理
- Pandas:合并四个品种的日度数据,处理缺失值,计算滚动相关系数
- Matplotlib:画出利润曲线的堆叠图,直观展示利润分配变化
- Statsmodels:做Granger因果检验,验证原油价格是否“引导”下游利润变化
你看,四个工具各司其职,缺一不可。没有NumPy,计算效率跟不上;没有Pandas,数据整理能累死人;没有可视化,分析结果说不清;没有统计模型,结论站不住脚。
嗯,这套工具栈,我用了快十年。每次遇到新问题,第一反应就是:这数据用Pandas怎么整理?这计算用NumPy怎么加速?这关系用Statsmodels怎么检验?
说白了,工具是死的,思路是活的。但前提是——你得先把这些工具练熟,练到它们成为你的肌肉记忆。