查看全课大纲(第 4 / 52 节)
  1. 1.量化分析基本概念:从咖啡馆到华尔街
  2. 2.量化交易员学习路线:从零基础到策略开发
  3. 3.量化策略生命周期:数据分析的五大流程
  4. 4.量化数据类型:数值型与类别型数据
  5. 5.量化沙盒搭建(1):Python与Anaconda安装
  6. 6.量化沙盒搭建(2):Jupyter Notebook与库配置
  7. 7.本地多源数据:量化历史回测的基石
  8. 8.TXT数据流操作:处理金融交易日志
  9. 9.JSON数据流操作:解析股票行情API响应
  10. 10.CSV行情文件操作:读取与存储历史K线
  11. 11.Excel报表操作:清洗财报与财务指标
  12. 12.量化数据库:SQL常用查询语法
  13. 13.量化数据库:Python连接与写入
  14. 14.量化多表连接:关联股票信息与行情
  15. 15.实战:小象咖啡店营业数据与个股财务指标的多源数据分析
  16. 16.量化数据采集:爬虫工作原理与合规
  17. 17.量化爬虫核心:URL管理与去重策略
  18. 18.量化网页下载:防反爬与请求头伪装
  19. 19.网页解析(1):使用XPath定位财经新闻
  20. 20.网页解析(2):使用CSS选择器与ItemLoader
  21. 21.Scrapy框架:构建工业级量化爬虫
  22. 22.Scrapy实战(1):新建项目与数据模型定义
  23. 23.Scrapy实战(2):编写财经爬虫逻辑
  24. 24.Scrapy实战(3):启用数据管道清洗行情
  25. 25.Scrapy实战(4):防反爬中间件配置
  26. 26.实战:构建每日热门个股行情自动采集系统
  27. 27.NumPy与SciPy:加速量化矩阵计算
  28. 28.NumPy数组:构建股票价格矩阵
  29. 29.数组切片:提取特定股票与交易日数据
  30. 30.NumPy常用方法:计算均值与波动率
  31. 31.向量化计算:摆脱缓慢的For循环
  32. 32.通用函数ufunc:计算对数收益率与累计收益
  33. 33.实战:股票组合资产收益率与协方差矩阵计算
  34. 34.Pandas Series:管理单只股票收盘价
  35. 35.Pandas DataFrame:构建多只股票行情面板
  36. 36.Pandas Index:时间序列索引与对齐
  37. 37.DataFrame索引操作:loc与iloc定位行情
  38. 38.索引总结:量化多字段筛选与定位
  39. 39.运算与对齐:合并不同交易日的数据
  40. 40.Pandas map:对股票代码与状态做映射
  41. 41.Pandas apply:滚动计算技术指标
  42. 42.排序操作:按市盈率与收益率对股票排名
  43. 43.数据清洗:填充与剔除停牌股票缺失值
  44. 44.数据清洗:剔除重复报价与异常交易数据
  45. 45.常用统计:量化最大回撤与分位数风险评估
  46. 46.极值定位:寻找历史最高价与最低价的发生日
  47. 47.风险与累计收益:计算年化波动率与累计回报
  48. 48.实战:小象咖啡店营业数据与热门个股时间序列清洗分析
  49. 49.Series索引操作:按位置与标签访问行情数据
  50. 50.文件读写操作:CSV行情数据导入导出
  51. 51.数据清洗:替换异常报价数据
  52. 52.常用统计:sum/mean/median/count聚合指标

量化数据类型:数值型与类别型数据

约 8 分钟

小象实战讲义 · 量化交易Python入门:从咖啡馆到华尔街

量化分析的一切结论都建立在数据之上,而数据的第一课是分清类型。本节讲数值型与类别型这两大数据类型的区别:连续的收益率、成交量、波动率为什么是数值型;股票代码、行业板块、涨跌状态为什么是类别型;以及类型判断如何直接决定后续能用哪些统计方法与可视化方式。这是读懂后面所有数据操作代码的前提。

💡 核心导读

数据类型是数据分析的基础单元,决定了数据的存储方式与操作规则。本节将系统讲解Python中核心的数据类型及其应用场景,包括数值型、文本型、布尔型等基础类型,以及Pandas中的Series和DataFrame扩展类型。通过本章学习,您将掌握:1) 类型识别与转换方法 2) Pandas特殊类型处理技巧 3) 类型相关的内存优化策略。所有知识点均通过可运行的代码示例演示。


基础数据类型体系

标量类型

Python原生支持的四种核心类型:

price = 99.5
quantity = 3
product = "显示器"
in_stock = True

print(f"类型检查:\n{type(price)=}\n{type(quantity)=}\n{type(product)=}\n{type(in_stock)=}")
类型检查:
type(price)=<class 'float'>
type(quantity)=<class 'int'>
type(product)=<class 'str'>
type(in_stock)=<class 'bool'>

容器类型

复合数据结构的典型代表:

specs = ["4K分辨率", "HDR10", "Type-C接口"]
inventory = {"A001": 15, "B205": 3}

print(f"列表 specs: {specs}")
print(f"字典 inventory: {inventory}")
print(f"浮点转字符串: {str(3.14)}")
print(f"字符串转整型: {int('1024')}")
print(f"字符串转列表: {list('ABCD')}")
列表 specs: ['4K分辨率', 'HDR10', 'Type-C接口']
字典 inventory: {'A001': 15, 'B205': 3}
浮点转字符串: 3.14
字符串转整型: 1024
字符串转列表: ['A', 'B', 'C', 'D']

Pandas扩展类型

Series类型

一维带标签数组的创建与操作:

import pandas as pd

stock_data = {"苹果公司仓": 42, "谷歌公司仓": 37, "亚马逊仓": 59}
series = pd.Series(stock_data, name="库存量")

print("Series数据类型:")
print(series.dtype)
print("\n值数组:")
print(series.values)
print("\n索引数组:")
print(series.index)
Series数据类型:
int64

值数组:
[42 37 59]

索引数组:
Index(['苹果公司仓', '谷歌公司仓', '亚马逊仓'], dtype='str')

DataFrame类型

二维表格数据的核心操作:

import pandas as pd

data = {
    "产品ID": ["P1001", "P1002", "P1003"],
    "单价(元)": [2999, 1599, 899],
    "库存状态": ["充足", "缺货", "充足"],
    "是否新品": [True, False, True]
}
df = pd.DataFrame(data)

print("DataFrame概览:")
print(df)
print("\n数据类型明细:")
print(df.dtypes)

执行后输出示例:

DataFrame概览:
    产品ID  单价(元) 库存状态   是否新品
0  P1001   2999   充足   True
1  P1002   1599   缺货  False
2  P1003    899   充足   True

数据类型明细:
产品ID       str
单价(元)    int64
库存状态       str
是否新品      bool
dtype: object

类型优化技巧

内存节省策略

import pandas as pd

data = {
    "产品ID": ["P1001", "P1002", "P1003"],
    "单价(元)": [2999, 1599, 899],
    "库存状态": ["充足", "缺货", "充足"],
    "是否新品": [True, False, True]
}
df = pd.DataFrame(data)

print("优化前内存使用:")
print(df.memory_usage(deep=True))

df["产品ID"] = df["产品ID"].astype('category')
df["是否新品"] = df["是否新品"].astype('int8')

print("\n优化后内存使用:")
print(df.memory_usage(deep=True))
优化前内存使用:
Index    132
产品ID     162
单价(元)     24
库存状态     210
是否新品       3
dtype: int64

优化后内存使用:
Index    132
产品ID     165
单价(元)     24
库存状态     210
是否新品       3
dtype: int64

时间类型处理

import pandas as pd

date_str = ["2023-01-15", "2023-02-20", "2023-03-10"]
dates = pd.to_datetime(date_str)

delta = dates.max() - dates.min()
print(f"最早与最晚日期相差: {delta.days}天")
最早与最晚日期相差: 54天

📝 动手练一练

第 1 题 · 概念应用

在构建一个简单的股票筛选模型时,你需要处理以下数据字段。请判断每个字段在 Pandas 中应优先使用哪种数据类型进行存储,并说明理由。

  1. stock_code: 股票代码,如 ‘000001.SZ’。
  2. close_price: 每日收盘价,如 18.56。
  3. industry: 所属行业,如 ‘银行’、‘医药生物’,共有 30 个不同的行业。
  4. is_st: 是否为 ST 股票,取值为 True 或 False。
  5. trade_date: 交易日期,如 ‘2024-05-10’。

请从以下选项中选择最合适的组合:

  • A. object, float64, object, bool, object
  • B. category, float32, category, int8, datetime64[ns]
  • C. object, float64, category, bool, datetime64[ns]
  • D. category, float64, object, int8, object
👉 点击查看参考答案

答案:C

推理过程:

  1. stock_code: 股票代码虽然是文本,但每个代码通常唯一,类别数量巨大(与股票数量相当)。将其转换为 category 类型的内存收益可能不大,甚至可能增加开销,因此保留为字符串类型即可(pandas 3 中字符串列的 dtype 显示为 str;早期版本显示为 object,本题选项沿用 object 这一历史写法,指的就是普通字符串列)。
  2. close_price: 收盘价是连续的数值,需要进行算术运算(如计算收益率),因此应使用数值型。float64 是 Pandas 默认的浮点类型,精度足够。
  3. industry: 行业是典型的类别型数据,且类别数量有限(仅30个)。使用 category 类型可以显著节省内存并提升某些分组操作的性能。
  4. is_st: 这是一个二值标签,bool 类型是最直接、最语义化的选择。
  5. trade_date: 日期数据应转换为 datetime64[ns] 类型,以便进行时间序列分析、计算时间差等操作。

选项 C 完美匹配了上述分析。选项 B 将 close_price 设为 float32 虽可省内存,但可能引入精度损失,非优先推荐;将 is_st 设为 int8 虽也可行,但不如 bool 直观。选项 A 和 D 未将 industry 或 trade_date 转换为更高效的类型。


第 2 题 · 代码填空

在分析股票估值时,我们常将市净率(PB)进行离散化处理,以便按估值水平分组。以下代码尝试使用等频分箱(即每个箱内数据量大致相等)将 PB 值分为“低”、“中”、“高”三组。请填入正确的 Pandas 分箱函数名。

import pandas as pd
import numpy as np

# 模拟10只股票的PB数据
pb_data = pd.Series([0.8, 1.2, 2.5, 3.8, 0.9, 1.5, 5.1, 2.2, 1.8, 4.0])
labels = ['低估值', '中等估值', '高估值']

# 使用等频分箱,将数据分为3组
pb_group = pd.______(pb_data, q=3, labels=labels)

print(pb_group.value_counts().sort_index())
👉 点击查看参考答案

空位应填:qcut

完整可运行代码:

import pandas as pd
import numpy as np

# 模拟10只股票的PB数据
pb_data = pd.Series([0.8, 1.2, 2.5, 3.8, 0.9, 1.5, 5.1, 2.2, 1.8, 4.0])
labels = ['低估值', '中等估值', '高估值']

# 使用等频分箱,将数据分为3组
pb_group = pd.qcut(pb_data, q=3, labels=labels)

print(pb_group.value_counts().sort_index())

输出结果:

低估值     4
中等估值    3
高估值     3
Name: count, dtype: int64

解释:

  • pd.qcut 根据样本分位数进行分箱,确保每个箱内的数据量尽可能相等。参数 q=3 表示分成3个等频区间。
  • 由于总数据点数为10,无法完全平均分配,所以分组结果为低估值组4个,中、高估值组各3个。
  • 与之相对的 pd.cut 是根据指定的数值边界进行分箱,常用于等宽分箱。本题要求等频,故应使用 qcut。

本章小结

📋 行动清单

  • 使用pd.to_numeric()将字符串列”销售数量”转换为数值型,处理其中可能存在的无效字符
  • 创建包含1000个随机整数的Series,对比astype('int32')与astype('int8')的内存占用差异
  • 用pd.Categorical()优化包含重复文本(如省份名称)的DataFrame列,记录内存节省比例

—— 小象教研组