Pandas是Python中一个强大的数据分析和处理库。它提供了高性能、易用的数据结构和数据分析工具。Pandas的核心是DataFrame数据结构,可以让你高效地操作和分析结构化数据。下面我来详细介绍一下Pandas的主要功能和用法:
- 数据结构:
- Series: 一维标记的同构数据结构,类似于一维数组
- DataFrame: 二维标记的异构表格结构,包含行列标签,类似于电子表格或SQL表
- 数据导入和导出:
- read_csv(), read_excel(), read_sql()等函数可从各种文件和数据库中导入数据
- to_csv(), to_excel(), to_sql()等函数可将数据导出到文件或数据库
- 数据清洗和预处理:
- 处理缺失值: isnull(), fillna(), dropna()
- 去重: drop_duplicates()
- 数据类型转换: astype()
- 数据排序: sort_values(), sort_index()
- 数据选取和过滤:
- 按标签选取: df.loc[行标签, 列标签]
- 按位置选取: df.iloc[行号, 列号]
- 布尔索引过滤: df[df['列名']>某值]
- 数据运算和聚合:
- 算术运算: add(), sub(), mul(), div()
- 统计聚合: sum(), mean(), max(), min(), count()
- 分组聚合: groupby()
- 数据透视表: pivot_table()
- 数据可视化:
- 绘图函数: plot(), hist(), boxplot(), scatter()等
- 时间序列处理:
- 时间戳和时间段: Timestamp, Period
- 日期范围: date_range()
- 频率转换: resample()
- 移动窗口计算: rolling()
我们以一个包含股票量化数据的CSV文件为例,讲解Pandas的数据结构以及如何导入和导出数据。
假设我们有一个名为"stock_data.csv"的文件,内容如下:
Date,Open,High,Low,Close,Volume
2023-01-03,100.5,101.3,99.8,100.2,1000000
2023-01-04,100.3,100.8,99.5,100.6,1200000
2023-01-05,100.7,101.5,100.1,101.2,1500000
...
- 导入数据到DataFrame:
import pandas as pddf = pd.read_csv('stock_data.csv')
print(df.head())
输出:
Date Open High Low Close Volume
0 2023-01-03 100.5 101.3 99.8 100.2 1000000
1 2023-01-04 100.3 100.8 99.5 100.6 1200000
2 2023-01-05 100.7 101.5 100.1 101.2 1500000
pd.read_csv()函数将CSV文件读取为一个DataFrame对象。DataFrame是一个二维标记的数据结构,每列可以是不同的数据类型。
这里'Date'列是日期,'Open','High','Low','Close'是浮点数,'Volume'是整数。
- 选取和过滤数据:
# 选取单列
closes = df['Close']
print(type(closes))# 选取多列
price_data = df[['Open', 'High', 'Low', 'Close']]# 过滤数据
high_volume = df[df['Volume'] > 1000000]
单列选取返回的是Series,多列选取返回的是子DataFrame。我们可以方便地用布尔条件筛选数据。
- 导出数据到CSV文件:
price_data.to_csv('price_data.csv', index=False)
to_csv()方法可将DataFrame导出为CSV文件。index=False表示不要将行索引也输出。
- 导出数据到Excel文件:
price_data.to_excel('price_data.xlsx', sheet_name='价格数据', index=False)
to_excel()将DataFrame导出到Excel文件,可以指定工作表名称。
假设我们的DataFrame df 中有一些缺失值和重复数据,并且Volume列的数据类型是字符串:
Date Open High Low Close Volume
0 2023-01-03 100.5 101.3 99.8 100.2 1000000
1 2023-01-04 NaN 100.8 99.5 NaN 1200000
2 2023-01-05 100.7 101.5 100.1 101.2 1500000
3 2023-01-03 100.5 101.3 99.8 100.2 1000000
4 2023-01-06 101.3 NaN 100.5 100.9 '800000'
- 数据清洗和预处理
- 处理缺失值
# 删除包含缺失值的行
df_dropped = df.dropna()# 填充缺失值为0
df_filled = df.fillna(0)
dropna()函数删除包含缺失值的行,fillna()函数可以将缺失值填充为指定的值。
- 去除重复行
df_deduped = df.drop_duplicates()
drop_duplicates()函数可以去除重复的行。
- 数据类型转换
df['Volume'] = df['Volume'].astype(int)
astype()函数将Volume列转换为整数类型。
- 数据选取和过滤
- 按标签选取
# 选取单个值
open0103 = df.at[0, 'Open']# 选取一行
row0 = df.loc[0]# 选取一列
opens = df.loc[:, 'Open']# 选取多列
price_data = df.loc[:, 'Open':'Close']
at用于选取单个标量值,loc用于按标签选取行、列或子DataFrame。
- 按位置选取
# 选取单个值
open0 = df.iat[0, 1]# 选取一行
row0 = df.iloc[0]# 选取一列
column0 = df.iloc[:, 0] # 选取子DataFrame
subdf = df.iloc[:3, 1:5]
iat用于选取单个标量值,iloc用于按整数位置选取行、列或子DataFrame。
- 布尔索引过滤
# 选取'Open'大于100的行
high_open = df[df['Open'] > 100]# 选取'Volume'大于1000000且'Close'小于101的行
filtered = df[(df['Volume'] > 1000000) & (df['Close'] < 101)]
将布尔条件传给DataFrame的[]操作符可以高效地过滤数据。多个条件可以用 &(和)、|(或)连接。
假设我们有一个包含多只股票数据的DataFrame df:
Date Symbol Open High Low Close Volume
0 2023-01-03 AAPL 100.5 101.3 99.8 100.2 1000000
1 2023-01-03 GOOG 90.2 91.5 89.7 91.1 500000
2 2023-01-04 AAPL 100.3 100.8 99.5 100.6 1200000
3 2023-01-04 GOOG 91.3 92.0 90.5 91.7 600000
4 2023-01-05 AAPL 100.7 101.5 100.1 101.2 1500000
5 2023-01-05 GOOG 91.8 92.3 91.2 92.0 800000
- 数据运算
- 算术运算
# 计算价格变化
df['PriceChange'] = df['Close'] - df['Open']# 计算价格变化百分比
df['PctChange'] = (df['Close'] - df['Open']) / df['Open'] * 100
我们可以直接对DataFrame的列进行算术运算,生成新的列。
- 移动窗口计算
# 计算5日移动平均线
df['MA5'] = df.groupby('Symbol')['Close'].rolling(5).mean().reset_index(drop=True)
rolling()函数可以计算移动窗口的统计值,这里我们按Symbol分组,计算每只股票的5日移动平均收盘价。
- 数据聚合
- 描述性统计
# 计算每列的统计值
stats = df.describe()# 计算Volume列的统计值
volume_stats = df['Volume'].describe()
describe()函数计算DataFrame每列的常见统计值,如数量、均值、标准差、最小值、四分位数、最大值等。
- 分组聚合
# 按Symbol分组,计算平均值
group_mean = df.groupby('Symbol').mean()# 按Symbol分组,计算最大Volume
group_max_volume = df.groupby('Symbol')['Volume'].max()
groupby()函数可以按一列或多列的值对数据分组,然后对每组应用聚合函数。
- 透视表
# 按Symbol和Date汇总Volume
volume_pivot = df.pivot_table(index='Date', columns='Symbol', values='Volume', aggfunc='sum')
pivot_table()函数可以方便地创建透视表,按行列标签汇总数据。这里我们按日期和股票代码汇总成交量。
假设我们有一个包含单只股票数据的DataFrame df:
Date Open High Low Close Volume
0 2023-01-03 100.5 101.3 99.8 100.2 1000000
1 2023-01-04 100.3 100.8 99.5 100.6 1200000
2 2023-01-05 100.7 101.5 100.1 101.2 1500000
3 2023-01-06 101.3 102.0 100.5 100.9 1800000
4 2023-01-09 100.8 101.2 99.9 100.5 1300000
Pandas的DataFrame和Series对象有一个便捷的 plot() 方法,可以快速创建各种图表。它实际上是在封装Python的Matplotlib库。
- 线形图
# 绘制收盘价折线图
df.plot(x='Date', y='Close', kind='line', figsize=(10, 6))
我们指定Date列为x轴,Close列为y轴,图表类型为'line',绘制收盘价折线图。figsize参数设置图表大小。
- 柱状图
# 绘制成交量柱状图
df.plot(x='Date', y='Volume', kind='bar', figsize=(10, 6))
这里我们绘制日成交量的柱状图,只需将图表类型改为'bar'。
- 直方图
# 绘制收盘价分布直方图
df['Close'].plot(kind='hist', bins=20, figsize=(10, 6))
直方图可以显示一列数据的分布情况。bins参数设置直方图的条形数量。
- 箱线图
# 绘制收盘价箱线图
df.boxplot(column=['Close'], figsize=(10, 6))
箱线图可以显示一列数据的统计分布信息,包括最小值、第一四分位数、中位数、第三四分位数和最大值。
- 散点图
# 绘制开盘价和收盘价散点图
df.plot(x='Open', y='Close', kind='scatter', figsize=(10, 6))
散点图可以显示两列数据的相关性。这里我们查看开盘价和收盘价的关系。
时间序列数据在量化金融领域非常常见,如股票价格、交易量等都是时间序列。
假设我们有以下股票数据DataFrame df:
Date Open High Low Close Volume
0 2023-01-03 100.5 101.3 99.8 100.2 1000000
1 2023-01-04 100.3 100.8 99.5 100.6 1200000
2 2023-01-05 100.7 101.5 100.1 101.2 1500000
3 2023-01-06 101.3 102.0 100.5 100.9 1800000
4 2023-01-09 100.8 101.2 99.9 100.5 1300000
- 将字符串日期转换为日期时间索引
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)
我们先用 to_datetime() 函数将Date列转换为日期时间类型,然后用 set_index() 方法将其设置为DataFrame的索引。这样DataFrame就变成了一个时间序列。
- 重采样
# 按周重采样,计算最高价、最低价、开盘价、收盘价和成交量的均值
weekly_df = df.resample('W').agg({'Open': 'first','High': 'max','Low': 'min','Close': 'last','Volume': 'mean'
})
resample() 方法可以将时间序列转换为另一个频率。这里我们将日数据重采样为周数据,并计算每周的最高价、最低价、开盘价(第一个值)、收盘价(最后一个值)和平均成交量。
- 移动窗口计算
# 计算5日移动平均收盘价
df['MA5'] = df['Close'].rolling(window=5).mean()# 计算5日移动平均成交量,忽略NaN值
df['Volume_MA5'] = df['Volume'].rolling(window=5, min_periods=1).mean()
rolling() 方法可以计算移动窗口的统计值。这里我们计算5日移动平均收盘价和成交量。min_periods参数设置了最小非NaN值的数量,以处理时间序列开头或含有NaN值的情况。
- 移动窗口聚合
# 计算20日内最高价和最低价
df['20d_High'] = df['High'].rolling(window=20).max()
df['20d_Low'] = df['Low'].rolling(window=20).min()
这里我们计算了20日内的最高价和最低价,可以用于确定价格范围或支撑和阻力位。
- 日期范围生成
# 生成一个日期范围
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='B')
date_range() 函数可以生成一个指定频率的日期范围。这里我们生成了2023年的所有工作日('B'表示工作日)。这在需要对齐或填充时间序列数据时非常有用。