Appearance
Python投资分析入门
本章是专为投资分析设计的Python入门教程。不会讲用不到的知识,所有示例都围绕投资场景展开。即便你从未写过代码,跟着本章一步步操作也能上手。
Python基础语法
变量:给数据起个名字
变量就像一个带标签的盒子,你可以把数据放进去,之后用标签名来使用这些数据。
python
# 股票名称
stock_name = "贵州茅台"
# 当前价格(元)
price = 1680.50
# 涨跌幅(百分比)
change_pct = 2.35
# 是否是ST股
is_st = Falsestock_name是字符串(文本),用引号包裹price和change_pct是数字(浮点数),可以直接参与计算is_st是布尔值(True或False),表示"是"或"否"
变量命名规则:只能用字母、数字和下划线,不能用数字开头,不能用中文(虽然技术上可以,但不推荐)。
列表:一组有序数据
列表(List)用于存放一组有序的数据,用方括号 [] 表示。
python
# 一组股票代码
stocks = ["600519", "000858", "601318", "000333"]
# 一组收盘价
prices = [1680.50, 156.30, 48.75, 62.80]
# 获取第一个元素(Python从0开始计数)
print(stocks[0]) # 输出: 600519
# 获取最后一个元素
print(stocks[-1]) # 输出: 000333
# 计算列表长度
print(len(stocks)) # 输出: 4
# 添加一个元素
stocks.append("600036")投资场景中,列表常用于存放一组股票代码、一组价格数据等。
字典:带标签的数据
字典(Dictionary)用花括号 {} 表示,每个数据都有一个"键"(key)作为标签。
python
# 用字典描述一只股票的信息
stock = {
"code": "600519",
"name": "贵州茅台",
"price": 1680.50,
"pe": 25.3, # 市盈率
"market_cap": 21000 # 市值(亿元)
}
# 通过键来访问数据
print(stock["name"]) # 输出: 贵州茅台
print(stock["pe"]) # 输出: 25.3
# 添加新的信息
stock["industry"] = "白酒"字典适合描述一个具有多个属性的实体,比如一只股票有代码、名称、价格等多个属性。
条件判断:if/else
条件判断让程序根据不同情况执行不同操作。
python
price = 1680.50
ma20 = 1650.00 # 20日均线
if price > ma20:
print("价格在均线之上,趋势偏多")
elif price == ma20:
print("价格正好在均线位置")
else:
print("价格在均线之下,趋势偏空")投资场景示例——判断市盈率水平:
python
pe = 35
if pe < 0:
print("公司亏损,市盈率为负")
elif pe < 15:
print("市盈率较低,可能被低估(需结合行业判断)")
elif pe < 30:
print("市盈率适中")
else:
print("市盈率较高,注意估值风险")注意:elif 是"else if"的缩写,用于多个条件分支。
循环:重复执行操作
for循环用于遍历一组数据,逐个处理。
python
# 遍历多只股票,判断每只的价格水平
stocks = [
{"name": "贵州茅台", "price": 1680},
{"name": "五粮液", "price": 156},
{"name": "宁德时代", "price": 210},
]
for stock in stocks:
if stock["price"] > 500:
print(f"{stock['name']} 是高价股")
else:
print(f"{stock['name']} 不是高价股")上面代码中的 f"..." 叫 f-string,是Python中格式化字符串的写法。花括号 {} 中的内容会被替换为变量的值。
range循环示例——计算连续5天的累计涨幅:
python
daily_returns = [0.02, -0.01, 0.03, 0.015, -0.005]
cumulative = 0
for i in range(len(daily_returns)):
cumulative = cumulative + daily_returns[i]
print(f"第{i+1}天,累计涨幅: {cumulative:.2%}")
{cumulative:.2%}表示以百分比格式显示,保留2位小数。
函数:封装可复用的代码块
函数(Function)把一段常用的代码封装起来,取个名字,以后可以反复调用,不用重复写。
python
# 定义一个函数:计算涨跌幅
def calc_change(current, previous):
"""计算涨跌幅百分比"""
return (current - previous) / previous * 100
# 使用函数
change = calc_change(1680, 1650)
print(f"涨跌幅: {change:.2f}%") # 输出: 涨跌幅: 1.82%投资场景示例——判断是否满足买入条件:
python
def check_buy_signal(price, ma5, volume, avg_volume):
"""
检查是否满足买入信号
条件:价格站上5日均线 且 成交量放大超过1.5倍
"""
if price > ma5 and volume > avg_volume * 1.5:
return True
else:
return False
# 使用
signal = check_buy_signal(
price=25.6, ma5=24.8, volume=1500000, avg_volume=800000
)
if signal:
print("满足买入条件")
else:
print("不满足买入条件")三引号 """...""" 是文档字符串(docstring),用于解释函数的用途,是良好的编程习惯。
pandas:投资数据分析的核心工具
pandas是Python中处理表格数据的王牌库。你可以把它想象成一个超级加强版的Excel,能用代码操作。
什么是DataFrame
DataFrame(数据框)是pandas中最核心的数据结构,类似于Excel中的一个表格——有行有列,每列有列名。
创建DataFrame
python
import pandas as pd
# 从字典创建DataFrame
data = {
"日期": ["2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"],
"开盘": [1680, 1695, 1670, 1685],
"收盘": [1690, 1675, 1685, 1700],
"成交量": [25000, 28000, 22000, 30000],
}
df = pd.DataFrame(data)
print(df)输出:
日期 开盘 收盘 成交量
0 2024-01-02 1680 1690 25000
1 2024-01-03 1695 1675 28000
2 2024-01-04 1670 1685 22000
3 2024-01-05 1685 1700 30000查看数据基本信息
python
# 查看前3行
print(df.head(3))
# 查看数据形状(行数, 列数)
print(df.shape)
# 查看列名
print(df.columns)
# 查看数据类型
print(df.dtypes)
# 快速统计摘要
print(df.describe())选取列和行
python
# 选取单列(返回Series)
prices = df["收盘"]
# 选取多列
subset = df[["日期", "收盘"]]
# 选取第2行(索引从0开始)
row2 = df.iloc[2]
# 选取第1到第3行
rows1to3 = df.iloc[1:4]添加计算列
这是pandas最实用的功能之一——基于已有列计算新列。
python
# 计算每日涨跌幅
df["涨跌幅"] = (df["收盘"] - df["开盘"]) / df["开盘"] * 100
# 计算成交量的5日移动平均(这里数据量少,仅作演示)
df["成交量_均值"] = df["成交量"].mean()
print(df)筛选数据
python
# 筛选收盘价大于1680的日期
high_close = df[df["收盘"] > 1680]
# 多条件筛选:收盘>1680 且 成交量>25000
filtered = df[(df["收盘"] > 1680) & (df["成交量"] > 25000)]
print(filtered)注意多条件筛选的语法:每个条件要用括号包裹,& 表示"且",| 表示"或"。
排序
python
# 按收盘价降序排列
df_sorted = df.sort_values("收盘", ascending=False)
# 按日期升序排列
df_by_date = df.sort_values("日期")分组统计
假设你有多只股票的数据:
python
data = {
"股票": ["茅台", "茅台", "茅台", "五粮液", "五粮液", "五粮液"],
"日期": ["01-02", "01-03", "01-04", "01-02", "01-03", "01-04"],
"收盘": [1690, 1675, 1685, 156, 158, 155],
}
df = pd.DataFrame(data)
# 按股票分组,计算平均收盘价
avg_price = df.groupby("股票")["收盘"].mean()
print(avg_price)
# 按股票分组,计算多项统计
stats = df.groupby("股票")["收盘"].agg(["mean", "max", "min"])
print(stats)处理日期
在金融数据分析中,日期处理非常重要。
python
# 把字符串列转换为日期类型
df["日期"] = pd.to_datetime(df["日期"])
# 设置日期为索引
df = df.set_index("日期")
# 按日期范围选取数据
subset = df.loc["2024-01-02":"2024-01-04"]计算移动平均线
移动平均线(Moving Average,简称均线)是技术分析中最常用的指标之一。
python
# 假设df有一列"收盘"
df["MA5"] = df["收盘"].rolling(window=5).mean() # 5日均线
df["MA20"] = df["收盘"].rolling(window=20).mean() # 20日均线rolling(window=N).mean() 的意思是:取当前行和前N-1行的数据,计算平均值。前N-1行因为数据不够,结果会是NaN(缺失值),这是正常的。
计算涨跌幅和累计收益
python
# 每日涨跌幅(百分比变化)
df["daily_return"] = df["收盘"].pct_change() * 100
# 累计收益率
df["cum_return"] = (1 + df["daily_return"] / 100).cumprod() - 1pct_change() 是pandas内置方法,自动计算每行相对前一行的变化率。
处理缺失值
真实数据中经常会有缺失值(显示为NaN),需要处理。
python
# 检查缺失值
print(df.isnull().sum())
# 删除包含缺失值的行
df_clean = df.dropna()
# 用前一个有效值填充缺失值(金融数据常用)
df_filled = df.fillna(method="ffill")
# 用特定值填充
df_zero = df.fillna(0)金融数据中,fillna(method="ffill")(前向填充)是最常用的方式——用前一天的已知数据来填充当天的缺失值。
读取和保存CSV文件
CSV(Comma-Separated Values,逗号分隔值)是一种通用的表格文件格式,可以用Excel打开。
python
# 从CSV文件读取数据
df = pd.read_csv("stock_data.csv")
# 保存数据到CSV文件
df.to_csv("output.csv", index=False)index=False 表示不保存行索引,这在大多数情况下是你想要的。
综合实战示例
以下是一个完整的示例,综合运用上述知识,分析一只模拟股票的简单数据:
python
import pandas as pd
# 模拟10个交易日的数据
df = pd.DataFrame({
"日期": pd.date_range("2024-01-02", periods=10, freq="B"), # B=工作日
"开盘": [100, 102, 101, 103, 105, 104, 106, 108, 107, 109],
"收盘": [102, 101, 103, 105, 104, 106, 108, 107, 109, 111],
"最高": [103, 103, 104, 106, 106, 107, 109, 109, 110, 112],
"最低": [99, 100, 100, 102, 103, 103, 105, 106, 106, 108],
"成交量": [50000, 60000, 45000, 70000, 55000, 65000, 80000, 72000, 58000, 68000],
})
# 计算涨跌幅
df["涨跌幅%"] = (df["收盘"].pct_change() * 100).round(2)
# 计算5日均线
df["MA5"] = df["收盘"].rolling(window=5).mean().round(2)
# 标记涨跌
df["涨跌"] = df["收盘"].apply(lambda x: "涨" if x > 105 else "跌")
# 筛选涨幅超过1%的交易日
big_up = df[df["涨跌幅%"] > 1]
print("涨幅超过1%的交易日:")
print(big_up[["日期", "收盘", "涨跌幅%"]])
# 保存到CSV
df.to_csv("analysis_result.csv", index=False, encoding="utf-8-sig")
print("\n数据已保存到 analysis_result.csv")
encoding="utf-8-sig"可以确保CSV文件中的中文在Excel中正常显示。
学习建议
- 不要只看不练:把上面的每个代码示例都自己在Jupyter Notebook中运行一遍,修改参数看看结果有什么变化。
- 从修改开始:先理解示例代码,然后尝试修改——改股票名称、改条件、改计算方式。
- 遇到报错不要慌:仔细阅读错误信息,大部分报错是因为拼写错误或缩进不对。把错误信息复制到搜索引擎中,通常能找到解决方案。
- 不求全:不需要一次学完所有pandas操作。先掌握本章的内容,后续用到新功能时再学。
小结
- Python基础语法:变量、列表、字典、条件判断、循环、函数。这些是编程的积木块。
- pandas核心操作:DataFrame创建、选取、筛选、计算、排序、分组、日期处理、缺失值处理、文件读写。
- 所有示例都围绕投资场景设计,后续章节将用这些知识处理真实的A股数据。
下一步
下一章我们将学习如何用Python获取真实的A股股票数据,把本章学到的pandas技能用在实打实的数据上。