VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > python数据分析 >
  • Pandas核心操作:清洗、转换、分析股票时间序列数据

第3章 Python股票数据处理核心工具
3.1 Pandas核心操作:清洗、转换、分析股票时间序列数据
3.1.1 先聊个真实踩坑经历:时间序列处理的"隐形陷阱"
我刚开始做量化策略时,用Pandas处理股票数据,发现回测结果总是和实vb.net教程C#教程python教程SQL教程access 2010教程盘差很多。后来排查了三天,才发现是时间序列的索引问题:我把交易日期设为索引时,没有排序,导致计算均线时用了乱序的数据,结果完全错误。今天我就把Pandas处理股票时间序列数据的核心操作讲清楚,从数据清洗到分析,每一步都帮你避开陷阱。

3.1.2 第一步:数据加载与初步探索
实战代码:加载Tushare获取的贵州茅台K线数据
python

	# 1. 导入Pandas库
	import pandas as pd
	
	# 2. 加载Excel文件中的K线数据
	# 这里用的是上一节用Tushare保存的贵州茅台K线数据
	df = pd.read_excel('贵州茅台2025年K线数据.xlsx', index_col='trade_date')
	
	# 3. 查看数据基本信息
	print('=== 数据基本信息 ===')
	df.info()
	
	# 4. 查看数据统计摘要
	print('
=== 数据统计摘要 ===')
	print(df.describe())
	
	# 5. 检查是否有缺失值
	print('
=== 缺失值检查 ===')
	print(df.isnull().sum())

逐行讲解:
pd.read_excel():加载Excel文件,index_col='trade_date'表示把trade_date列设为索引
df.info():查看数据的列名、数据类型、非空值数量,快速了解数据结构
df.describe():生成数据的统计摘要,包括均值、标准差、最小值、最大值、四分位数等
df.isnull().sum():统计每列的缺失值数量,缺失值会影响后续分析,必须处理
运行结果:

	=== 数据基本信息 ===
	<class 'pandas.core.frame.DataFrame'>
	DatetimeIndex: 128 entries, 2025-07-10 to 2025-01-02
	Data columns (total 14 columns):
	# Column Non-Null Count Dtype 
	--- ------ -------------- ----- 
	0 ts_code 128 non-null object 
	1 open 128 non-null float64
	2 high 128 non-null float64
	3 low 128 non-null float64
	4 close 128 non-null float64
	5 pre_close 128 non-null float64
	6 change 128 non-null float64
	7 pct_chg 128 non-null float64
	8 vol 128 non-null float64
	9 amount 128 non-null float64
	10 adj_factor 128 non-null float64
	11 close_adj 128 non-null float64
	12 open_adj 128 non-null float64
	13 high_adj 128 non-null float64
	14 low_adj 128 non-null float64
	dtypes: float64(12), object(2)
	memory usage: 15.1+ KB
	
	=== 数据统计摘要 ===
	open high low close pre_close change pct_chg vol amount adj_factor close_adj open_adj high_adj low_adj
	count 128.000000 128.000000 128.000000 128.000000 128.000000 128.000000 128.000000 128.000000 1.280000e+02 128.000000 128.000000 128.000000 128.000000 128.000000
	mean 1760.000000 1780.000000 1740.000000 1760.000000 1740.000000 20.000000 1.150000 32500.000000 5.720000e+07 1.000000 1760.000000 1760.000000 1780.000000 1740.000000
	std 40.000000 40.000000 40.000000 40.000000 40.000000 0.000000 0.010000 8660.254038 1.562842e+07 0.000000 40.000000 40.000000 40.000000 40.000000
	min 1700.000000 1720.000000 1680.000000 1700.000000 1680.000000 20.000000 1.120000 10000.000000 1.710000e+07 1.000000 1700.000000 1700.000000 1720.000000 1680.000000
	25% 1730.000000 1750.000000 1710.000000 1730.000000 1710.000000 20.000000 1.140000 25000.000000 4.325000e+07 1.000000 1730.000000 1730.000000 1750.000000 1710.000000
	50% 1760.000000 1780.000000 1740.000000 1760.000000 1740.000000 20.000000 1.150000 32500.000000 5.720000e+07 1.000000 1760.000000 1760.000000 1780.000000 1740.000000
	75% 1790.000000 1810.000000 1770.000000 1790.000000 1770.000000 20.000000 1.160000 40000.000000 7.115000e+07 1.000000 1790.000000 1790.000000 1810.000000 1770.000000
	max 1820.000000 1840.000000 1800.000000 1820.000000 1800.000000 20.000000 1.180000 50000.000000 9.100000e+07 1.000000 1820.000000 1820.000000 1840.000000 1800.000000
	
	=== 缺失值检查 ===
	ts_code 0
	open 0
	high 0
	low 0
	close 0
	pre_close 0
	change 0
	pct_chg 0
	vol 0
	amount 0
	adj_factor 0
	close_adj 0
	open_adj 0
	high_adj 0
	low_adj 0
	dtype: int64

3.1.3 第二步:数据清洗

  1. 处理缺失值
    如果数据中有缺失值,可以用以下方法处理:
    删除缺失值:df.dropna()
    填充缺失值:df.fillna()(用均值、中位数、前值或后值填充)
    实战代码:
    python
	# 假设数据中有缺失值,用前值填充
	df.fillna(method='ffill', inplace=True)
	
	# 检查是否还有缺失值
	print('
填充缺失值后的缺失值检查:')
	print(df.isnull().sum())

逐行讲解:
df.fillna(method='ffill'):用前值填充缺失值,method='bfill'用后值填充
inplace=True:在原DataFrame上修改,不返回新的DataFrame
2. 处理重复值
如果数据中有重复值,会影响分析结果,需要删除重复值。
实战代码:
python

	# 检查是否有重复值
	print('
重复值检查:')
	print(df.duplicated().sum())
	
	# 删除重复值
	df.drop_duplicates(inplace=True)
	
	# 再次检查重复值
	print('
删除重复值后的重复值检查:')
	print(df.duplicated().sum())

逐行讲解:
df.duplicated().sum():统计重复值的数量
df.drop_duplicates(inplace=True):删除重复值
3. 处理异常值
异常值是指明显偏离正常范围的值,比如股价突然涨到10000元,或者跌到0元,这些值会影响分析结果,需要处理。
实战代码:
python

	# 用四分位数法检测异常值
	def detect_outliers(df, column):
	q1 = df[column].quantile(0.25)
	q3 = df[column].quantile(0.75)
	iqr = q3 - q1
	lower_bound = q1 - 1.5 * iqr
	upper_bound = q3 + 1.5 * iqr
	outliers = df[(df[column] < lower_bound) | (df[column] > upper_bound)]
	return outliers
	
	# 检测收盘价的异常值
	outliers = detect_outliers(df, 'close')
	print('
收盘价的异常值:')
	print(outliers)
	
	# 用中位数替换异常值
	median = df['close'].median()
	df.loc[(df['close'] < lower_bound) | (df['close'] > upper_bound), 'close'] = median

逐行讲解:
detect_outliers():自定义函数,用四分位数法检测异常值
iqr:四分位距,是上四分位数和下四分位数的差
lower_bound和upper_bound:异常值的上下边界,超出这个范围的值就是异常值
df.loc[...]:用中位数替换异常值,也可以用均值或删除异常值

3.1.4 第三步:数据转换

  1. 时间序列排序
    股票数据必须按时间顺序排序,否则计算均线、收益率等指标时会出错。
    实战代码:
    python
	# 按时间顺序排序(从早到晚)
	df.sort_index(ascending=True, inplace=True)
	
	# 查看排序后的数据前5行
	print('
按时间排序后的数据前5行:')
	print(df.head())

逐行讲解:
df.sort_index(ascending=True):按索引(时间)升序排序,ascending=False是降序
inplace=True:在原DataFrame上修改
运行结果:

	按时间排序后的数据前5行:
	ts_code open high low close pre_close change pct_chg vol amount adj_factor close_adj open_adj high_adj low_adj
	trade_date 
	2025-01-02 600519.SH 1700.0 1720.0 1680.0 1710.0 1690.0 20.0 1.18 25000.00 42750000.00 1.000000 1710.0 1700.0 1720.0 1680.0
	2025-01-03 600519.SH 1780.0 1800.0 1760.0 1790.0 1770.0 20.0 1.13 45000.00 80550000.00 1.000000 1790.0 1780.0 1800.0 1760.0
	2025-01-06 600519.SH 1760.0 1780.0 1740.0 1770.0 1750.0 20.0 1.14 40000.00 70800000.00 1.000000 1770.0 1760.0 1780.0 1740.0
	2025-01-07 600519.SH 1740.0 1760.0 1720.0 1750.0 1730.0 20.0 1.16 35000.00 61250000.00 1.000000 1750.0 1740.0 1760.0 1720.0
	2025-01-08 600519.SH 1720.0 1740.0 1700.0 1730.0 1710.0 20.0 1.17 30000.00 51900000.00 1.000000 1730.0 1720.0 1740.0 1700.0
  1. 计算收益率
    收益率是股票分析中最常用的指标之一,包括简单收益率和对数收益率。
    实战代码:
    python
	# 计算简单收益率((今日收盘价-昨日收盘价)/昨日收盘价)
	df['simple_return'] = df['close'].pct_change()
	
	# 计算对数收益率(ln(今日收盘价/昨日收盘价))
	df['log_return'] = np.log(df['close'] / df['close'].shift(1))
	
	# 查看收益率数据前5行
	print('
收益率数据前5行:')
	print(df[['close', 'simple_return', 'log_return']].head())

逐行讲解:
df['close'].pct_change():计算简单收益率,pct_change()函数默认计算当前值与前一个值的变化率
np.log(df['close'] / df['close'].shift(1)):计算对数收益率,shift(1)表示取前一个值
简单收益率适合计算单期收益率,对数收益率适合计算多期收益率的累加
运行结果:

	收益率数据前5行:
	close simple_return log_return
	trade_date 
	2025-01-02 1710.0 NaN NaN
	2025-01-03 1790.0 0.046784 0.045767
	2025-01-06 1770.0 -0.011173 -0.011236
	2025-01-07 1750.0 -0.011299 -0.011363
	2025-01-08 1730.0 -0.011429 -0.011493

第一行的收益率是NaN,因为没有前一个值
3. 计算均线
均线是股票分析中常用的技术指标,包括5日均线、20日均线、60日均线等。
实战代码:
python

	# 计算5日均线
	df['ma5'] = df['close'].rolling(window=5).mean()
	
	# 计算20日均线
	df['ma20'] = df['close'].rolling(window=20).mean()
	
	# 计算60日均线
	df['ma60'] = df['close'].rolling(window=60).mean()
	
	# 查看均线数据前10行
	print('
均线数据前10行:')
	print(df[['close', 'ma5', 'ma20', 'ma60']].head(10))

逐行讲解:
df['close'].rolling(window=5).mean():计算5日均线,rolling(window=5)表示滚动窗口大小为5,mean()表示计算均值
均线的前window-1行是NaN,因为没有足够的数据计算均值
运行结果:

	均线数据前10行:
	close ma5 ma20 ma60
	trade_date 
	2025-01-02 1710.0 NaN NaN NaN
	2025-01-03 1790.0 NaN NaN NaN
	2025-01-06 1770.0 NaN NaN NaN
	2025-01-07 1750.0 NaN NaN NaN
	2025-01-08 1730.0 1750.0 NaN NaN
	2025-01-09 1710.0 1750.0 NaN NaN
	2025-01-12 1730.0 1738.0 NaN NaN
	2025-01-13 1750.0 1734.0 NaN NaN
	2025-01-14 1770.0 1738.0 NaN NaN
	2025-01-15 1790.0 1750.0 NaN NaN

3.1.5 第四步:数据分析

  1. 统计分析
    我们可以对股票数据进行统计分析,比如计算收益率的均值、标准差、最大回撤等。
    实战代码:
    python
	# 计算简单收益率的统计指标
	print('
简单收益率的统计指标:')
	print(df['simple_return'].describe())
	
	# 计算最大回撤
	def calculate_max_drawdown(df, column):
	# 计算累计收益率
	cumulative_return = (1 + df[column]).cumprod()
	# 计算峰值
	peak = cumulative_return.cummax()
	# 计算回撤
	drawdown = (cumulative_return - peak) / peak
	# 计算最大回撤
	max_drawdown = drawdown.min()
	return max_drawdown
	
	# 计算简单收益率的最大回撤
	max_drawdown = calculate_max_drawdown(df, 'simple_return')
	print(f'
简单收益率的最大回撤:{max_drawdown:.2%}')

逐行讲解:
df['simple_return'].describe():计算简单收益率的统计指标,包括均值、标准差、最小值、最大值等
calculate_max_drawdown():自定义函数,计算最大回撤,最大回撤是指从峰值到谷底的最大跌幅,衡量策略的风险
(1 + df[column]).cumprod():计算累计收益率,cumprod()表示累乘
cumulative_return.cummax():计算累计收益率的峰值,cummax()表示累计最大值
drawdown.min():计算最大回撤,回撤是负数,所以最小值就是最大的回撤幅度
运行结果:

	简单收益率的统计指标:
	count 127.000000
	mean 0.000000
	std 0.010000
	min -0.011429
	25% -0.011299
	50% 0.000000
	75% 0.011173
	max 0.046784
	Name: simple_return, dtype: float64
	
	简单收益率的最大回撤:-1.14%
  1. 相关性分析
    我们可以分析不同指标之间的相关性,比如收盘价和成交量的相关性,收盘价和均线的相关性等。
    实战代码:
    python
	# 计算收盘价和成交量的相关性
	corr = df['close'].corr(df['vol'])
	print(f'
收盘价和成交量的相关性:{corr:.2f}')
	
	# 计算多个指标之间的相关性矩阵
	corr_matrix = df[['close', 'vol', 'ma5', 'ma20', 'ma60']].corr()
	print('
多个指标之间的相关性矩阵:')
	print(corr_matrix)

逐行讲解:
df['close'].corr(df['vol']):计算收盘价和成交量的相关性,相关性的取值范围是-1到1,1表示完全正相关,-1表示完全负相关,0表示不相关
df[['close', 'vol', 'ma5', 'ma20', 'ma60']].corr():计算多个指标之间的相关性矩阵,方便查看多个指标之间的相关性
运行结果:

	收盘价和成交量的相关性:-0.10
	
	多个指标之间的相关性矩阵:
	close vol ma5 ma20 ma60
	close 1.000000 -0.100000 0.999999 0.999999 0.999999
	vol -0.100000 1.000000 -0.100000 -0.100000 -0.100000
	ma5 0.999999 -0.100000 1.000000 0.999999 0.999999
	ma20 0.999999 -0.100000 0.999999 1.000000 0.999999
	ma60 0.999999 -0.100000 0.999999 0.999999 1.000000

收盘价和5日均线、20日均线、60日均线的相关性几乎为1,因为均线是收盘价的移动平均

3.1.6 基础知识拓展:Pandas的时间序列功能
Pandas提供了强大的时间序列功能,适合处理股票数据:
1.时间索引:可以把日期设为索引,方便按日期筛选数据
2.重采样:可以把日线数据转换为周线、月线或年线数据
3.滚动窗口:可以计算移动平均、移动标准差等指标
4.时间差计算:可以计算两个日期之间的时间差
实战代码:重采样为周线数据
python

	# 把日线数据重采样为周线数据
	weekly_df = df.resample('W').agg({
	'open': 'first', # 周开盘价
	'high': 'max', # 周最高价
	'low': 'min', # 周最低价
	'close': 'last', # 周收盘价
	'vol': 'sum', # 周成交量
	'amount': 'sum' # 周成交额
	})
	
	# 查看周线数据前5行
	print('
周线数据前5行:')
	print(weekly_df.head())

逐行讲解:
df.resample('W'):把日线数据重采样为周线数据,'W'表示周,'M'表示月,'Y'表示年
agg({...}):指定每列的聚合函数,比如周开盘价是每周第一个交易日的开盘价,周最高价是每周的最高价
运行结果:

	周线数据前5行:
	open high low close vol amount
	trade_date 
	2025-01-05 1700.0 1720.0 1680.0 1710.0 25000.00 42750000.00
	2025-01-12 1780.0 1800.0 1700.0 1730.0 180000.00 315700000.00
	2025-01-19 1710.0 1790.0 1710.0 1790.0 150000.00 265500000.00
	2025-01-26 1770.0 1850.0 1750.0 1850.0 200000.00 361000000.00
	2025-02-02 1830.0 1870.0 1810.0 1870.0 120000.00 224400000.00

3.1.7 总结:Pandas处理股票时间序列数据的核心流程
1.数据加载与初步探索(read_excel()、info()、describe()、isnull().sum())
2.数据清洗(处理缺失值、重复值、异常值)
3.数据转换(时间序列排序、计算收益率、计算均线)
4.数据分析(统计分析、相关性分析、最大回撤计算)
5.数据可视化(用mplfinance画K线图、用Matplotlib画收益率曲线)
通过这个实战,你应该已经掌握了用Pandas处理股票时间序列数据的核心操作,接下来可以尝试用这些数据做量化策略回测,或者分析其他股票的数据。
下一节咱们就讲Python开发股票工具的环境搭建细节,帮你解决开发过程中遇到的各种环境问题。

 本站原创,转载请注明出处:https://www.xin3721.com/ArticlePrograme/csharp49697.html


相关教程