第3章:Pandas基础——Series与DataFrame创建、数据读取与概览
说实话,做金融数据可视化,Pandas 就是你的瑞士军刀。我见过太多人一上来就搞 matplotlib 画图,结果数据没清洗干净,画出来的图全是错的。嗯,咱们先把地基打牢。
这一章,我带你搞定三个核心动作:创建数据结构、读取外部文件、快速浏览数据。这三个动作,我在每个金融项目里至少重复几十遍。
3.1 Series:一维数据容器
Series 说白了就是带标签的一维数组。你可以把它想象成 Excel 里的一列,既有数据,又有行号(索引)。
创建 Series 最简单的方式就是传一个列表:
import pandas as pd
# 从列表创建
s1 = pd.Series([100, 200, 300, 400])
print(s1)
输出长这样:
0 100
1 200
2 300
3 400
dtype: int64
左边是索引,右边是数据。默认索引从0开始。但我个人习惯给索引起个有意义的名字,比如股票代码:
s2 = pd.Series([28.5, 45.2, 67.8], index=['000001', '000002', '000003'])
print(s2)
这样一眼就能看出哪个价格对应哪只股票。我在做基金净值跟踪时,经常用日期做索引:
import datetime
dates = pd.date_range('2024-01-01', periods=5, freq='D')
s3 = pd.Series([1.02, 1.03, 1.01, 1.05, 1.04], index=dates)
print(s3)
pd.date_range() 生成日期索引,比手动写日期列表快得多。我每次做时间序列分析都这么干。
3.2 DataFrame:二维数据表格
DataFrame 才是重头戏。你可以把它理解成一张 Excel 表格,有行有列,每列可以存不同类型的数据。
创建 DataFrame 最常用的方式是用字典:
data = {
'股票代码': ['000001', '000002', '000003'],
'收盘价': [28.5, 45.2, 67.8],
'成交量': [123456, 234567, 345678],
'日期': ['2024-01-01', '2024-01-01', '2024-01-01']
}
df = pd.DataFrame(data)
print(df)
输出:
股票代码 收盘价 成交量 日期
0 000001 28.5 123456 2024-01-01
1 000002 45.2 234567 2024-01-01
2 000003 67.8 345678 2024-01-01
你看,字典的键变成了列名,值变成了列数据。我曾经犯过一个错——字典里值的长度不一致,结果报错了。所以创建时一定要保证每列长度相同。
另一种常见方式是从列表的列表创建,同时指定列名:
data_list = [
['000001', 28.5, 123456],
['000002', 45.2, 234567],
['000003', 67.8, 345678]
]
df2 = pd.DataFrame(data_list, columns=['股票代码', '收盘价', '成交量'])
print(df2)
columns 参数,列名会默认变成0、1、2…… 这在后续处理中非常容易搞混。我建议每次都显式指定列名。
3.3 数据读取:CSV 与 Excel
实际工作中,数据很少手动输入。大部分时候是从 CSV 或 Excel 文件读取。我处理过的金融数据文件,少则几千行,多则上百万行。
读取 CSV 文件
# 读取CSV文件
df_csv = pd.read_csv('stock_data.csv')
print(df_csv.head())
这里有几个参数我几乎每次都用:
encoding='utf-8'或'gbk'—— 中文文件经常编码不对,我遇到过好几次乱码问题parse_dates=['日期']—— 自动把日期列转成 datetime 类型index_col='日期'—— 把日期列设为行索引
举个例子:
df_csv = pd.read_csv(
'stock_data.csv',
encoding='utf-8',
parse_dates=['日期'],
index_col='日期'
)
sep=None 让 Pandas 自动检测分隔符。
读取 Excel 文件
Excel 文件在金融行业特别常见。很多券商、基金公司提供的报表都是 .xlsx 格式。
# 读取Excel文件
df_excel = pd.read_excel('fund_report.xlsx', sheet_name='净值数据')
print(df_excel.head())
常用参数:
sheet_name—— 指定工作表名称,可以是字符串或数字(0表示第一个工作表)header—— 指定哪一行作为列名,默认是第一行skiprows—— 跳过前几行,有些报表开头有说明文字
我记得有一次,一个 Excel 文件前3行都是公司名称和报告标题,第4行才是真正的列名。我用了 header=3 才搞定。
df_excel = pd.read_excel(
'fund_report.xlsx',
sheet_name='净值数据',
header=3
)
3.4 数据概览:快速了解你的数据
数据读进来之后,第一件事不是分析,而是「看一眼」。我一般用三个方法:head()、info()、describe()。
head() —— 看前几行
print(df.head()) # 默认前5行
print(df.head(10)) # 前10行
print(df.tail(3)) # 后3行
这个函数帮我快速确认数据是否读对了。比如列名对不对、数据有没有明显异常。
info() —— 看整体结构
print(df.info())
输出类似这样:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1000 entries, 2024-01-01 to 2026-09-25
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 股票代码 1000 non-null object
1 收盘价 998 non-null float64
2 成交量 1000 non-null int64
3 最高价 995 non-null float64
4 最低价 995 non-null float64
dtypes: float64(3), int64(1), object(1)
memory usage: 46.9 KB
这里信息量很大:
- 总共有多少行、多少列
- 每列的数据类型(Dtype)
- 每列有多少个非空值(Non-Null Count)
你看「收盘价」只有998个非空值,总共有1000行。说明有2个缺失值。这就是 info() 的价值——一眼发现数据质量问题。
describe() —— 看统计摘要
print(df.describe())
输出:
收盘价 成交量 最高价 最低价
count 998.000000 1.000000e+03 995.000000 995.000000
mean 45.321000 2.345678e+05 46.120000 44.890000
std 8.765000 1.234567e+05 8.900000 8.600000
min 20.100000 1.000000e+04 21.000000 19.800000
25% 38.500000 1.500000e+05 39.200000 38.000000
50% 45.000000 2.200000e+05 45.800000 44.500000
75% 52.300000 3.000000e+05 53.100000 51.700000
max 78.900000 6.000000e+05 80.000000 77.500000
这个函数只对数值列有效。它告诉你:
- count:非空值数量(再次确认缺失情况)
- mean:平均值
- std:标准差(波动性)
- min/max:最小最大值
- 25%/50%/75%:四分位数
做金融分析时,我特别关注 min 和 max。如果收盘价最小值是负数,那肯定有问题——股票价格不可能为负。这就是数据清洗的信号。
3.5 本章知识体系
下面这张图帮你理清本章的核心逻辑:
说白了,这一章就三件事:造数据、读数据、看数据。别小看这三个动作,我见过太多人数据都没看清楚就开始画图,结果图上的异常值把整个分析带偏了。
嗯,今天就到这儿。记住:拿到数据先 info() 再 describe(),这是我在每个项目里的固定套路。
公众号:蓝海资料掘金营,微信deep3321