3. 数据读取与初步探索:读取CSV/Excel文件、查看数据基本信息

好了,咱们正式开始动手了。

上一章聊了聊景气度数据长什么样,这一章咱们就直接把数据请进 Python 里来。我个人习惯,拿到任何数据文件,第一件事不是跑模型,而是先把它读进来,然后好好“打量”一番——看看它长什么样、有没有缺胳膊少腿、数据类型对不对。

说白了,这一步就像你拿到一份新简历,先扫一眼基本信息,心里有个底。

3.1 读取CSV文件:最常用的姿势

CSV 文件在量化投资领域太常见了。交易所的日频数据、行业分类数据、宏观指标,十有八九都是 CSV 格式。我一般用 pandasread_csv 函数,简单直接。

import pandas as pd

# 读取CSV文件
df = pd.read_csv('景气度数据.csv')
print('数据读取成功!')

嗯,就这么一行。但这里有个坑——编码问题。我在项目中遇到过好几次,从万得导出的 CSV 文件,默认编码是 gbkgb2312,直接用 read_csv 读会报错。解决办法很简单:

df = pd.read_csv('景气度数据.csv', encoding='gbk')
# 如果还不行,试试 encoding='gb2312' 或 encoding='utf-8'
⚠️ 注意: 如果文件路径包含中文,建议在路径字符串前加 r 变成原始字符串,或者用双反斜杠。比如 r'C:\data\景气度.csv'

3.2 读取Excel文件:多Sheet也不怕

Excel 文件在业务部门用得更多。很多券商的研究报告、行业数据库,都喜欢用 Excel 格式。读取 Excel 用 pd.read_excel()

# 读取Excel文件
df = pd.read_excel('景气度数据.xlsx', sheet_name='Sheet1')

如果你要读取多个 Sheet,可以传一个列表:

# 读取多个Sheet
dfs = pd.read_excel('景气度数据.xlsx', sheet_name=['Sheet1', 'Sheet2'])
# 返回的是一个字典,key是Sheet名,value是DataFrame

我曾经有一次处理一个季度数据,Excel 文件里有 12 个 Sheet,每个 Sheet 代表一个月的行业景气度。用 sheet_name=None 一次性全读进来,然后循环处理,效率很高。

💡 小技巧: 如果 Excel 文件很大,可以加 nrows=1000 参数先读前 1000 行看看结构,避免一次性加载太慢。

3.3 查看数据基本信息:head、info、describe

数据读进来了,接下来就是“打量”它。我一般按这个顺序来:

3.3.1 用 head() 看前几行

# 查看前5行
df.head()

这能让你快速了解数据长什么样——有哪些列、数据大概是什么格式。我习惯先看 head(10),多几行更容易发现异常。

3.3.2 用 info() 看数据类型和缺失值

# 查看数据基本信息
df.info()

这个函数会告诉你:

  • 总共有多少行、多少列
  • 每列的数据类型(int64、float64、object 等)
  • 每列有多少个非空值
  • 内存占用情况

举个例子,输出可能是这样的:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1200 entries, 0 to 1199
Data columns (total 8 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   日期         1200 non-null   object 
 1   行业         1200 non-null   object 
 2   景气度指数    1150 non-null   float64
 3   营收增速      1100 non-null   float64
 4   利润增速      1080 non-null   float64
 5   库存周转      1200 non-null   float64
 6   产能利用率    1050 non-null   float64
 7   毛利率        1120 non-null   float64
dtypes: float64(6), object(2)
memory usage: 75.1 KB

看到没?日期列是 object 类型,这其实不对。日期应该转成 datetime 类型,否则后面做时间序列分析会出问题。这个我们下一章会处理。

另外,景气度指数只有 1150 个非空值,总共有 1200 行,说明有 50 个缺失值。嗯,这里要注意,缺失值怎么处理,后面会专门讲。

3.3.3 用 describe() 看统计摘要

# 查看数值型列的统计摘要
df.describe()

输出类似这样:

景气度指数 营收增速 利润增速 库存周转 产能利用率 毛利率
count 1150.0 1100.0 1080.0 1200.0 1050.0 1120.0
mean 52.3 8.5 6.2 45.1 78.3 22.5
std 15.2 12.3 18.7 8.9 10.5 5.6
min 10.0 -30.5 -45.2 20.0 45.0 8.0
25% 40.0 2.0 -5.0 38.0 70.0 18.0
50% 52.0 8.0 5.0 45.0 80.0 22.0
75% 65.0 15.0 18.0 52.0 88.0 27.0
max 90.0 55.0 60.0 70.0 98.0 40.0

这个表能告诉你很多信息:

  • 均值和中位数:如果两者差距很大,说明数据可能有偏态分布
  • 最小值/最大值:看看有没有离谱的异常值。比如营收增速最小是 -30.5%,最大是 55%,这还算正常。但如果出现 -9999 这种,那肯定是脏数据
  • count 列:再次确认缺失值情况
🔍 实战经验: 我在做行业轮动策略时,有一次发现某个行业的景气度指数最小值是 0,但其他行业都是 10 以上。查了半天,原来是数据源把缺失值填成了 0。这种“假数据”如果不处理,策略回测结果会完全失真。

3.4 数据类型概览:别让类型坑了你

数据类型是数据清洗的第一步。我见过太多人栽在这个坑里——明明应该是数值的列,读进来却是字符串;明明应该是日期的列,读进来却是 object。

dtypes 属性可以快速查看每列的类型:

# 查看所有列的数据类型
print(df.dtypes)

输出:

日期         object
行业         object
景气度指数    float64
营收增速      float64
利润增速      float64
库存周转      float64
产能利用率    float64
毛利率        float64
dtype: object

常见的类型问题:

  • 数值列是 object 类型:可能是因为数据里混入了逗号(比如 "1,234")或百分号(比如 "22.5%")
  • 日期列是 object 类型:需要转成 datetime,否则没法做时间序列分析
  • 整数列是 float64 类型:可能是因为有缺失值,pandas 会自动转成 float

怎么处理?举个例子:

# 把日期列转成 datetime 类型
df['日期'] = pd.to_datetime(df['日期'])

# 如果数值列里有百分号,先去掉再转
df['毛利率'] = df['毛利率'].str.replace('%', '').astype(float) / 100
⚠️ 注意: 转换类型时,如果数据里有无法转换的值(比如 "N/A"),会报错。可以用 errors='coerce' 参数,让无法转换的值变成 NaN。

3.5 本章知识体系

下面这张图总结了本章的核心逻辑,你可以把它当作一个检查清单:

数据读取与初步探索流程 读取数据 read_csv / read_excel 查看基本信息 head() / info() / describe() 检查数据类型 dtypes / 类型转换 ⚠️ 常见问题:编码错误 ⚠️ 常见问题:缺失值 ⚠️ 常见问题:类型错误 核心目标 确认数据完整性 → 识别数据类型 → 发现潜在问题

这张图把本章的三个核心步骤串起来了:读取数据 → 查看基本信息 → 检查数据类型。每一步都可能遇到坑,但只要你按这个流程走一遍,基本不会漏掉关键信息。

好了,数据已经读进来了,基本信息也看过了。下一章咱们聊聊怎么处理那些烦人的缺失值和异常值——这可是数据清洗的重头戏。


专注资料整理