Spark大数据处理 + Matplotlib数据可视化
本实验采用贵州茅台公司从2005年1月4日到2025年9月30日期间的每日股票行情数据,并搭建伪分布式Hadoop环境,使用HDFS存储数据,Spark处理数据,最后采用Matplotlib做数据可视化结果展示
目录
- 数据集获取
- 数据预处理
- 数据存储和数据分析
- 数据可视化
数据集获取
选取贵州茅台(股票代码:600519.SH),使用智兔数服金融数据API,数据时间跨度(2005年~2025年),包含5000多条数据,字段说明如下
本实验完整数据,可以后台私信,或者在智兔官网使用API自行获取
数据预处理
接下来对空值和异常值进行处理(从接口获取的数据往往是有空缺和异常值的)
首先查找空值和异常值0的行(注意:有些字段如sf字段为0并不是异常值
)
查看异常数据分布情况可以看出,存在连续行异常情况,使用前值填充的方式对数据进行补全比较合理(70行左右含异常0值)。
数据存储和数据分析
将处理好的数据process_data.csv上传到HDFS文件系统,并使用Spark进行数据分析
- 年平均交易量
代码如下
python
from pyspark import SparkConf
from pyspark.sql.types import * # 使用的这里面的 Row
from pyspark.sql import SparkSession
from datetime import datetime
import pyspark.sql.functions as func
#主程序
spark = SparkSession.builder.config(conf=SparkConf()).appName("Read HDFS CSV").getOrCreate()
schema = StructType([StructField('t', DateType(), False),
StructField("o", FloatType(), False),
StructField("h", FloatType(), False),
StructField("l", FloatType(), False),
StructField("c", FloatType(), False),
StructField("v", FloatType(), False),
StructField("a", FloatType(), False),
StructField("pc", FloatType(), False),
StructField("sf", IntegerType(), False)])
# 读取 HDFS CSV 并应用 schema
df = (spark.read
.format("csv")
.option("header", "true")# 若 CSV 无表头,设为 "false" 并通过 schema 定义字段名
.option("dateFormat","yyyyMMdd")# 若日期格式特殊,指定格式(如 "MM/dd/yyyy")
.schema(schema)# 应用自定义 schema
.load("/user/hadoop/stock/process_data.csv"))
df.show(3)
# 将日期字段转换为年份
df = df.withColumn("year", func.year("t"))
# 计算每年的平均交易量
yearly_avg_volume = df.groupBy("year").agg({"v": "avg"}).orderBy("year")
# 显示结果
print("每年的平均交易量:")
yearly_avg_volume.show()
运行结果如下
- 分析股票收盘价的波动
提供两种实现思路(对收盘价进行分析)
①当涉及数据不是特别复杂使用
python
# 计算收盘价的平均值和标准差
closing_stats = df.select(avg("c").alias("avg_close"),stddev("c").alias("stddev_close"))
# 显示结果
print("平均收盘价和标准差:")
closing_stats.show()
②使用sql语句完成,对sql熟练的同学友好
python
# 创建视图并使用SQL分析
df.createTempView("stockData")
# 2. 分析股票收盘价的波动
print("2.分析股票收盘价的波动")
spark.sql("SELECT AVG(c) AS avg_close,STDDEV(c) AS stddev_close FROM stockData").show()
运行结果
- 分析贵州茅台近20年的最高股价和最低股价
最高股价
最低股价
在数据集中的最高股价出现在2021年2月18日,为2627.88元;而最低股价出现在2005年1月4日,为36.0元。
- 各月份涨停跌停次数统计
补充知识:
涨停&跌停
- 涨停条件:
- sf = 0:只统计正常交易日(排除停牌日);
- pc > 0:排除前一日收盘价为 0 的异常数据(避免计算涨跌幅时除数为 0);
(c - pc) / pc * 100 >= 9.9
:涨跌幅≥9.9%,判定为涨停(考虑四舍五入误差,比 10% 更合理)。- 跌停条件:与涨停相反,跌停的涨跌幅计算公式为:
(c - pc) / pc * 100% ≤ -9.9%
涨停次数统计结果展示:
跌停次数统计结果展示
可以看到3,4,5,9这几个月份更容易出现涨跌停现象。
- 统计每年上涨和下跌的天数
执行结果
可以发现近几年下跌的天数要比上涨的天数要高
数据可视化
将上面的分析结果保存为csv文件,下面使用 matplotlib更进行生动展示结果
- 每年的股票平均交易量
代码如下
python
def result1():
avg_v = pd.read_csv("./stock_results/result1/part-00000.csv")
# 绘制柱状图
plt.figure(figsize=(12, 6))
plt.bar(avg_v['year'], avg_v['avg_volume'], color='b', label='Average Volume')
plt.xticks(
avg_v['year'], # 使用数据中的年份作为x轴刻度
rotation=45, # 旋转45度
ha='center' # 旋转后标签右对齐,避免超出图表范围
)
# 设置图表标题和标签
plt.title('Yearly Average Stock Volume')
plt.xlabel('Year')
plt.ylabel('Average Volume')
plt.tight_layout()
plt.show()
将数据保存到本地,使用pandas来加载数据,matplotlib绘制柱状图
- 可视化每个月涨跌停次数
使用饼图更好的展示占比情况,其中去除了值为0的月份(即当月没有涨停或跌停)
- 可视化每年上涨和下跌的天数
采用柱状图展示每年上涨和下跌的对比情况,并使用堆叠柱状图进行展示,其中绿色代表上涨,红色代表下跌
- 近20年贵州茅台股票价格曲线图

- 近一年的股票趋势图
以上所有分析结果,基于智兔股票数据API接口,本文
只作为学习用途,禁止转载,严禁用于商业用途