Skip to content

Python投资分析入门

本章是专为投资分析设计的Python入门教程。不会讲用不到的知识,所有示例都围绕投资场景展开。即便你从未写过代码,跟着本章一步步操作也能上手。

Python基础语法

变量:给数据起个名字

变量就像一个带标签的盒子,你可以把数据放进去,之后用标签名来使用这些数据。

python
# 股票名称
stock_name = "贵州茅台"
# 当前价格(元)
price = 1680.50
# 涨跌幅(百分比)
change_pct = 2.35
# 是否是ST股
is_st = False
  • stock_name 是字符串(文本),用引号包裹
  • pricechange_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() - 1

pct_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中正常显示。

学习建议

  1. 不要只看不练:把上面的每个代码示例都自己在Jupyter Notebook中运行一遍,修改参数看看结果有什么变化。
  2. 从修改开始:先理解示例代码,然后尝试修改——改股票名称、改条件、改计算方式。
  3. 遇到报错不要慌:仔细阅读错误信息,大部分报错是因为拼写错误或缩进不对。把错误信息复制到搜索引擎中,通常能找到解决方案。
  4. 不求全:不需要一次学完所有pandas操作。先掌握本章的内容,后续用到新功能时再学。

小结

  • Python基础语法:变量、列表、字典、条件判断、循环、函数。这些是编程的积木块。
  • pandas核心操作:DataFrame创建、选取、筛选、计算、排序、分组、日期处理、缺失值处理、文件读写。
  • 所有示例都围绕投资场景设计,后续章节将用这些知识处理真实的A股数据。

下一步

下一章我们将学习如何用Python获取真实的A股股票数据,把本章学到的pandas技能用在实打实的数据上。

下一章:获取股票数据

仅供学习交流,不构成任何投资建议