49 创建序列和数据框
本章定位(复习与补充训练层):本章对应正课第10章《Pandas Series和DataFrame创建》(章节 10),用于复习、补缺与额外练习。建议先不看讲解,直接尝试下方平台任务,再对照解析补弱项。本章不属于必修主线。先做本章『动手与思考』第 1 题与平台任务自测,通过即可跳过本章。
49.1 引言 Pandas数据结构在金融分析中的核心地位
Pandas 是 Python 数据分析的核心库,建立在 NumPy 之上,提供了 Series 与 DataFrame 两种数据结构。本章围绕”创建 Series—创建 DataFrame—设置索引—结构互转”复习这些能力,并完成平台四个任务。
49.2 本章学习目标
通过本章的复习与补充训练,你将能够:
- 用
pd.Series(data, index)创建一维序列,并说明列表、字典、NumPy 数组三种数据源下索引分别来自哪里 - 用
pd.DataFrame(data, index=..., columns=...)创建二维数据框,分清行索引与列名各自的作用 - 在 Series、DataFrame、NumPy 数组、Python 列表之间互相转换(
list()、np.array()、.values) - 用
pd.date_range()与set_index()为数据框设置有意义的日期行标签,并用type()确认对象类型,独立完成平台四个任务
49.3 创建Series对象
Series是Pandas的一维数据结构,可以理解为”带标签的数组”。在金融应用中,Series非常适合存储单只股票的价格序列、单只股票的交易量序列、或某一天的多个股票价格等一维数据。
既然 NumPy 数组已经能装下这些数值,为什么还需要 Series?因为 NumPy 数组在数据分析中存在三个关键限制。
理论背景:从NumPy到Pandas的演进
NumPy数组提供了高效的数值计算能力,但在数据分析中存在三个关键限制:
- 缺乏标签:NumPy数组只能通过整数位置访问,无法使用有意义的标签(如股票代码、日期)
- 数据类型单一:NumPy数组的所有元素必须是相同类型
- 缺失值处理:NumPy使用NaN表示缺失值,但处理不够灵活
Pandas通过Series和DataFrame这两种数据结构完美解决了这些问题,使其成为金融数据分析的理想工具。
平台任务(平台原始代码)
以下代码与教学平台任务要求完全一致:
任务要求:任务一,用国泰金鑫 8 个交易日的净值数组与交易日数组创建带日期索引的 Series,并把某日 5 只基金净值列表转为以基金简称为索引的 Series,分别查看两者类型;任务二,用 3 只基金 3 个交易日的净值数组创建数据框,行索引取日期切片、列名取基金名切片,并查看其类型;任务三,用 8 个交易日 × 5 只基金的净值数组创建完整净值数据框并打印;任务四,把 Series 转为列表、把 Series 与 DataFrame 分别转为 NumPy 数组,并打印数据框转出的数组。请将代码原样输入教学平台(注释除外),判定以平台为准。
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
#任务一
import numpy as np
import pandas as pd # 导入Pandas数据分析库
value_guotai = np.array([1.5284,1.4596,1.3745,1.4034,1.3935,1.39,1.412,1.4164]) #国泰金鑫股票基金2024年8月1日起的8个交易日(至8月12日)净值数据的数组
date = np.array(["2024-08-01","2024-08-02","2024-08-05","2024-08-06","2024-08-07","2024-08-08","2024-08-09","2024-08-12"]) #交易日数组
series_guotai = pd.Series(data=value_guotai,index=date) #创建序列
print(type(series_guotai)) #查看变量的数据结构
data=[1.4596,1.001,0.897,2.051,1.7385];index=["国泰金鑫","中海医疗","华夏优势","富国城镇","上投摩根"] #创建8月2日基金净值的数组
value_0403 = pd.Series(data,index) # 创建Series序列value_0403
print(type(value_0403)) # 输出数据类型
#任务二
import numpy as np
import pandas as pd # 导入Pandas数据分析库
date = np.array(["2024-08-01","2024-08-02","2024-08-05","2024-08-06","2024-08-07","2024-08-08","2024-08-09","2024-08-12"]) #交易日数组
name = np.array(["国泰金鑫","中海医疗","华夏优势","富国城镇","上投摩根"]) #基金名称的数组并且用基金简称
data_3fund_array = np.array([[1.01,0.8918,2.038],[0.995,0.8833,2.025],[1.002,0.8735,2.032]]) #3只基金在2024年8月8日至12日净值的数组
data_3fund = pd.DataFrame(data=data_3fund_array,index=date[5:],columns=name[1:4]) #转成一个数据框
print(type(data_3fund)) # 输出数据类型
#任务三
import numpy as np
import pandas as pd # 导入Pandas数据分析库
date = np.array(["2024-08-01","2024-08-02","2024-08-05","2024-08-06","2024-08-07","2024-08-08","2024-08-09","2024-08-12"]) #交易日数组
name = np.array(["国泰金鑫","中海医疗","华夏优势","富国城镇","上投摩根"]) # 创建NumPy数组name
# 创建NumPy数组value_total
value_total = np.array([[1.5284,0.991,0.9122,2.069,1.7742],[1.4596,1.001,0.897,2.051,1.7385],[1.3745,1,0.8786,2.023,1.6843],[1.4034,1.013,0.8944,2.027,1.6917],
[1.3935,1.007,0.8944,2.031,1.6957],[1.39,1.01,0.8918,2.038,1.6955],[1.412,0.995,0.8833,2.025,1.6938],[1.6938,1.002,0.8735,2.032,1.6899]]) #创建数组
data_total = pd.DataFrame(data=value_total,index=date,columns=name) #转为数据框
print(data_total) # 输出数据数据
#任务四
import numpy as np
import pandas as pd # 导入Pandas数据分析库
value_guotai = np.array([1.5284,1.4596,1.3745,1.4034,1.3935,1.39,1.412,1.4164]) #国泰金鑫股票基金2024年8月1日起的8个交易日(至8月12日)净值数据的数组
date = np.array(["2024-08-01","2024-08-02","2024-08-05","2024-08-06","2024-08-07","2024-08-08","2024-08-09","2024-08-12"]) #交易日数组
series_guotai = pd.Series(data=value_guotai,index=date) # 创建Series序列series_guotai
data=[1.4596,1.001,0.897,2.051,1.7385];index=["国泰金鑫","中海医疗","华夏优势","富国城镇","上投摩根"] #创建8月2日基金净值的数组
value_0403 = pd.Series(data,index) # 创建Series序列value_0403
name = np.array(["国泰金鑫","中海医疗","华夏优势","富国城镇","上投摩根"]) #基金名称的数组并且用基金简称
data_3fund_array = np.array([[1.01,0.8918,2.038],[0.995,0.8833,2.025],[1.002,0.8735,2.032]])#3只基金在2024年8月8日至12日净值的数组
data_3fund = pd.DataFrame(data=data_3fund_array,index=date[5:],columns=name[1:4]) # 创建数据框data_3fund
list_guotai = list(series_guotai)#国泰金鑫8与1日到12日净值数据的序列转为列表
array_0403 = np.array(value_0403) #8月2日5只基金净值的序列转为数组
array_3fund = data_3fund.values #8月8日到12日3只基金净值的数据框变为数组
print(array_3fund) # 输出基金数据题面笔误提示:任务三
value_total末行国泰金鑫 2024-08-12 取值 1.6938,与任务一/任务四同日的 1.4164 不一致(疑为题面串行笔误)。请按平台原始题面原样输入,以平台判定为准。
预期输出(本机 Python 实际运行结果,四个任务在同一代码块中顺序执行;具体以平台运行结果为准):
- 任务一:两行类型输出
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
- 任务二:一行类型输出
<class 'pandas.core.frame.DataFrame'> - 任务三:打印 8 行 × 5 列的净值数据框,行索引为 2024-08-01 至 2024-08-12 的 8 个交易日,列名依次为国泰金鑫、中海医疗、华夏优势、富国城镇、上投摩根;首行
1.5284 0.991 0.9122 2.069 1.7742,末行(含题面笔误值)1.6938 1.002 0.8735 2.032 1.6899 - 任务四:打印任务二数据框转出的 3×3 NumPy 数组:
[[1.01 0.8918 2.038 ]
[0.995 0.8833 2.025 ]
[1.002 0.8735 2.032 ]]
# =============================================================================
# 题目:创建Pandas Series对象
# =============================================================================
# 本任务演示三种不同的Series创建方法,适用于不同的数据来源场景
# ==================== 导入必要的库 ====================
# pandas:Python数据分析的核心库
import pandas as pd
# numpy:Python科学计算的基础库,pandas依赖numpy
import numpy as np
# ==================== 方法1:从Python列表创建Series ====================
# 场景:当你有一系列数值数据需要存储为Series时
# 列表[10, 20, 30, 40, 50]包含5个整数元素
# pd.Series()函数将列表转换为Series对象
# Series会自动为这些元素创建默认的整数索引(0, 1, 2, 3, 4)
s1 = pd.Series([10, 20, 30, 40, 50])
# 结果:一个Series对象,值为[10, 20, 30, 40, 50],索引为[0, 1, 2, 3, 4]
# ==================== 方法2:从字典创建Series ====================
# 场景:当你有键值对数据,且键本身就是有意义的标签时
# 字典的键(股票名称)会成为Series的索引
# 字典的值(股价)会成为Series的值
# name参数指定Series的名称,用于标识这个Series
s2 = pd.Series({
'贵州茅台': 1850, # 键'贵州茅台',值1850(股价)
'五粮液': 220, # 键'五粮液',值220(股价)
'招商银行': 45 # 键'招商银行',值45(股价)
}, name='股价') # 设置Series名称为'股价'
# 结果:一个Series对象,索引为['贵州茅台', '五粮液', '招商银行']
# 值为[1850, 220, 45],名称为'股价'
# ==================== 方法3:从NumPy数组创建Series ====================
# 场景:当你有数值计算的结果需要转换为Series时
# np.random.randn(5)生成5个标准正态分布的随机数(均值0,标准差1)
# 这些随机数可以用于模拟股票收益率等金融数据
np.random.seed(42) # 固定随机种子,保证每次运行结果一致
s3 = pd.Series(np.random.randn(5))
# 结果:一个Series对象,包含5个随机数,索引为默认的[0, 1, 2, 3, 4]
# ==================== 打印输出Series对象 ====================
print('Series 1 (从列表创建):')
print(s1) # 输出Series的完整表示:索引、值、数据类型
print('\nSeries 2 (从字典创建):')
print(s2) # 输出带名称的Series
print(f'索引: {s2.index.tolist()}') # .index获取索引对象,.tolist()转换为Python列表
# 输出:['贵州茅台', '五粮液', '招商银行']代码深度解析:
- Series的组成结构:
- 索引(index):每个数据点的标签,用于定位和访问数据
- 值(values):实际存储的数据
- 名称(name):Series对象的标识(可选)
- 数据类型(dtype):值的类型(如int64、float64、object等)
- 从字典创建的优势:
- 索引自动设置为字典的键,无需手动指定
- 适合表示有标签的数据(如股票名称到价格的映射)
- 比从列表创建后设置索引更简洁
- Series与NumPy数组的关系:
- Series基于NumPy数组构建
- Series.values返回底层的NumPy数组
- Series比NumPy数组多了索引功能
49.4 创建DataFrame
DataFrame是Pandas的二维数据结构,类似于Excel表格或SQL数据库的表。在金融分析中,DataFrame是最常用的数据结构,用于存储和分析多只股票的多指标数据。把 Series 与 DataFrame 放在一起对照,两种结构的分工一目了然:
Pandas两种核心数据结构:
| 特性 | Series | DataFrame |
|---|---|---|
| 维度 | 一维 | 二维 |
| 类比 | 带标签的数组 | 带标签的表格/Excel工作表 |
| 索引 | 必须有索引 | 必须有行索引,列名是另一种索引 |
| 金融应用 | 单只股票的价格序列 | 多只股票的多指标数据表 |
# =============================================================================
# 题目:创建Pandas DataFrame对象
# =============================================================================
# 本任务演示如何从字典创建DataFrame来存储股票数据
# ==================== 从字典创建DataFrame ====================
# 场景:当你的数据是以字典形式组织时,每个键是一个列名,每个值是列数据
# 字典的键('股票代码', '股票名称', '股价', '涨跌幅')将成为DataFrame的列名
# 字典的值都是列表,这些列表的长度必须相同(这里都是3个元素)
data = {
'股票代码': ['600519.SH', '000858.SZ', '600036.SH'], # 第一列:股票代码
'股票名称': ['贵州茅台', '五粮液', '招商银行'], # 第二列:公司名称
'股价': [1850.0, 220.5, 45.2], # 第三列:股价(浮点数)
'涨跌幅': [0.05, -0.02, 0.03] # 第四列:涨跌幅(浮点数)
}
# pd.DataFrame()函数将字典转换为DataFrame对象
# Pandas会自动:
# 1. 使用字典的键作为列名
# 2. 对齐所有列表的数据(创建3行×4列的表格)
# 3. 自动生成默认的行索引(0, 1, 2)
df = pd.DataFrame(data)
# ==================== 打印DataFrame的基本信息 ====================
print('DataFrame内容:')
print(df)
# 输出格式:
# 股票代码 股票名称 股价 涨跌幅
# 0 600519.SH 贵州茅台 1850.0 0.05
# 1 000858.SZ 五粮液 220.5 -0.02
# 2 600036.SH 招商银行 45.2 0.03
# 左侧的0,1,2是行索引,顶部是列名
# ==================== 查看DataFrame的属性 ====================
print(f'\nDataFrame形状: {df.shape}') # shape属性返回(行数, 列数)
# 输出:(3, 4) - 表示3行4列的表格
print(f'列名列表: {df.columns.tolist()}') # columns获取所有列名,tolist()转换为列表
# 输出:['股票代码', '股票名称', '股价', '涨跌幅']49.5 从NumPy数组创建DataFrame
在科学计算和金融建模中,数据往往以NumPy数组的形式产生(如数值模拟的结果、矩阵运算的结果)。将NumPy数组转换为DataFrame可以添加有意义的标签,使数据更易读和易分析。
# =============================================================================
# 题目:从NumPy数组创建DataFrame
# =============================================================================
# 本任务演示如何将NumPy数值数组转换为带标签的DataFrame
# ==================== 创建随机NumPy数组 ====================
# np.random.randn(5, 3)生成一个5行×3列的数组
# 5行:5个观测样本(如5个交易日或5只股票)
# 3列:每个样本有3个特征(如开盘价、最高价、最低价)
# 这些数据服从标准正态分布(均值0,标准差1)
np.random.seed(42) # 固定随机种子,保证每次运行结果一致
arr = np.random.randn(5, 3)
# 结果:一个5×3的NumPy数组,包含随机数值
# ==================== 将NumPy数组转换为DataFrame ====================
# pd.DataFrame()函数可以将NumPy数组转换为DataFrame
# arr参数:要转换的NumPy数组(数据来源)
# columns参数:指定DataFrame的列名(列表形式)
# index参数:指定DataFrame的行标签(列表形式)
df_random = pd.DataFrame(
arr, # 数据来源:5×3的随机数组
columns=['特征1', '特征2', '特征3'], # 列名:为3列分别命名
index=['样本1', '样本2', '样本3', '样本4', '样本5'] # 行标签:为5行分别命名
)
# 结果:一个5×3的DataFrame,行标签为"样本1"到"样本5",列名为"特征1"到"特征3"
# ==================== 打印DataFrame ====================
print('从NumPy数组创建的DataFrame:')
print(df_random)
# 输出格式:
# 特征1 特征2 特征3
# 样本1 随机值1 随机值2 随机值3
# 样本2 随机值1 随机值2 随机值3
# ...(共5行)49.6 从列表的列表创建DataFrame
当数据以嵌套列表的形式组织时(例如从CSV文件读取的数据,或从API获取的JSON数据),也可以直接创建DataFrame。
# =============================================================================
# 题目:从列表的列表创建DataFrame
# =============================================================================
# 本任务演示如何将嵌套列表转换为DataFrame
# ==================== 准备嵌套列表数据 ====================
# 场景:当你有多个记录,每个记录包含多个字段时
# 外层列表包含3个元素(3条股票记录)
# 每个元素是一个列表,包含[名称, 价格, 涨跌幅]三个字段
data_list = [
['贵州茅台', 1850.0, 0.05], # 第1条记录
['五粮液', 220.5, -0.02], # 第2条记录
['招商银行', 45.2, 0.03] # 第3条记录
]
# data_list是一个"列表的列表"结构
# ==================== 从列表的列表创建DataFrame ====================
# pd.DataFrame()函数可以接受嵌套列表作为输入
# data_list参数:数据源(嵌套列表)
# columns参数:指定列名,为每列数据赋予有意义的名称
# - '名称':第一列数据(股票名称)
# - '价格':第二列数据(股价)
# - '涨跌幅':第三列数据(涨跌百分比)
df_from_list = pd.DataFrame(
data_list, # 数据:嵌套列表
columns=['名称', '价格', '涨跌幅'] # 列名:指定3个列的名称
)
# Pandas会自动将嵌套列表的每个子列表对应到一行
# 子列表的第0个元素对应第1列,第1个元素对应第2列,以此类推
# ==================== 打印DataFrame ====================
print('从列表的列表创建的DataFrame:')
print(df_from_list)
# 输出格式:
# 名称 价格 涨跌幅
# 0 贵州茅台 1850.0 0.05
# 1 五粮液 220.5 -0.02
# 2 招商银行 45.2 0.0349.7 设置DataFrame的索引
索引(Index)是Pandas数据结构的重要特性,它为每行数据提供了一个有意义的标识。在金融时间序列分析中,通常将日期设置为索引,以便进行时间序列操作(如按日期切片、重采样等)。
# =============================================================================
# 题目:设置DataFrame的行索引
# =============================================================================
# 本任务演示如何为DataFrame设置有意义的行标签
# ==================== 创建示例DataFrame ====================
# 创建一个简单的DataFrame用于演示
df = pd.DataFrame({
'价格': [10, 20, 30, 40, 50], # 第1列:价格数据
'销量': [100, 200, 150, 300, 250] # 第2列:销量数据
})
# 默认会创建整数索引0, 1, 2, 3, 4
# ==================== 生成日期序列作为索引 ====================
# pd.date_range()函数生成日期序列(DatetimeIndex对象)
# '2024-01-01':起始日期
# periods=5:生成5个日期
# 默认频率是'D'(每天),也可以指定'B'(工作日)、'M'(月)等
dates = pd.date_range('2024-01-01', periods=5)
# 结果:DatetimeIndex(['2024-01-01', '2024-01-02', ..., '2024-01-05'])
# ==================== 将日期设置为DataFrame的索引 ====================
# set_index()方法将某列(或外部数据)设置为行索引
# dates参数:使用前面生成的日期序列作为新索引
# 原来的整数索引(0, 1, 2, 3, 4)会被替换
df_indexed = df.set_index(dates)
# 结果:DataFrame的行索引变成了日期,而不是数字
# ==================== 打印带日期索引的DataFrame ====================
print('带日期索引的DataFrame:')
print(df_indexed)
# 输出格式:
# 价格 销量
# 2024-01-01 10 100
# 2024-01-02 20 200
# 2024-01-03 30 150
# ...(共5行)
# 左侧是日期索引,不再是0, 1, 2...
# ==================== 索引的好处 ====================
# 现在可以使用日期来选择数据,例如:
# df_indexed.loc['2024-01-01'] # 获取特定日期的数据
# df_indexed.loc['2024-01-01':'2024-01-03'] # 获取日期范围的数据
# 这比使用整数位置(如df.iloc[0:3])更直观、更不容易出错49.8 本章小结
要点:
- Series 是带标签的一维数组,由
index(标签)与values(数据)构成,可选name标识;DataFrame 是带行索引与列名的二维表 - 数据源决定写法:列表或 NumPy 数组作数据时需另外给出
index/columns;字典的键自动成为 Series 的索引或 DataFrame 的列名 - 双向转换:
.values把 Series/DataFrame 还原为 NumPy 数组,list()把 Series 转为列表,np.array()、pd.Series()、pd.DataFrame()在四类结构之间自由搬运 set_index()用日期等有意义的标签替换默认整数索引,为后续按标签切片、时间序列操作打基础;type()是确认对象类型的第一手段
易错点:
index长度必须与数据长度一致、columns数量必须与列数一致,否则构造直接报错- 用字典构造 DataFrame 时各值列表的长度必须相同,长短不一会抛错
- 平台任务二用
date[5:]、name[1:4]切片截取部分索引,切片结果与数据行列数对不上是高频报错来源(3 行数据配 3 个日期、3 个基金名) pd.Series(data, index)的两个位置参数顺序容易写反,改用关键字参数data=、index=更稳妥- Series 打印时会同时输出索引、数值与 dtype 三部分,不要把 dtype 行误认为数据的一部分
49.9 动手与思考
以下练习每题附参考答案(默认折叠)。请先独立完成并写下你的判断,再点开对照,最后上机验证。
输出预测:不运行代码,先写出下面代码的输出结果,再上机检验你的判断。
import pandas as pd s = pd.Series([10, 20, 30], index=['a', 'b', 'c']) print(s['b']) print(s.values) df = pd.DataFrame({'价格': [1.0, 2.0], '数量': [3, 4]}, index=['甲', '乙']) print(df.shape) print(df.columns.tolist())参考答案(先写下你的预测再点开)
解题思路:
s['b']按标签取出标量20;s.values剥掉索引,返回 NumPy 数组[10 20 30](注意打印形式没有逗号)。字典构造 DataFrame 时键成为列名,故df.shape为(2, 2)(2 行 2 列),df.columns.tolist()为['价格', '数量']。# 验证脚本:Series取值与DataFrame结构 import pandas as pd # 导入pandas库 s = pd.Series([10, 20, 30], index=['a', 'b', 'c']) # 显式指定标签索引的序列 print(s['b']) # 按标签取单个值,输出标量20 print(s.values) # 只取数据部分,返回NumPy数组 df = pd.DataFrame({'价格': [1.0, 2.0], '数量': [3, 4]}, index=['甲', '乙']) # 字典键作列名 print(df.shape) # 输出(行数,列数) print(df.columns.tolist()) # 列名转为列表输出预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):
20 [10 20 30] (2, 2) ['价格', '数量']回扣主线:Series 的索引/数据两要素与
.values的双向转换见第 章节 10 章。自测回忆:不看正文,分别说明从列表和从字典创建 Series 时,索引分别由谁提供;再写出把 Series 转为列表、把 DataFrame 转为 NumPy 数组的语句。
参考答案(点开前请先独立完成)
解题思路:从列表创建 Series 时,索引默认由 Pandas 提供整数位置索引(0、1、2……),除非显式传入
index;从字典创建 Series 时,字典的键自动成为索引。转换语句:Series 转列表用list(s)或s.tolist();DataFrame 转 NumPy 数组用df.values。# 验证脚本:两种数据源的索引来源与双向转换 import pandas as pd # 导入pandas库 s = pd.Series([10, 20, 30], index=['a', 'b', 'c']) # 列表作数据、显式给索引 print(list(s), s.tolist()) # Series转列表的两种写法 df = pd.DataFrame({'价格': [1.0, 2.0], '数量': [3, 4]}, index=['甲', '乙']) # 建数据框 print(type(df.values), df.values.dtype) # DataFrame转NumPy数组并查看类型预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):
[10, 20, 30] [10, 20, 30] <class 'numpy.ndarray'> float64回扣主线:“数据源决定写法”与四类结构的双向转换见第 章节 10 章”要点”第 2、3 条。
变式任务(平台任务同型改造):参照平台任务二,用 3 个交易日和 2 只基金构造一个 3×2 的净值数据框,再用
.values取出其数组形式并打印,对照两者行列方向的对应关系。参考答案(点开前请先独立完成)
解题思路:用二维嵌套结构作数据、
index给 3 个交易日、columns给 2 只基金,得到 3×2 数据框;.values取出的数组行对应交易日、列对应基金——DataFrame 的行方向与数组的第 1 维、列方向与第 2 维一一对应,打印后逐行对照即可验证。# 变式脚本:3日×2基金净值数据框与其数组形式 import pandas as pd # 导入pandas库 import numpy as np # 导入NumPy库 nav_dates = ['2024-01-02', '2024-01-03', '2024-01-04'] # 3个交易日作行索引 fund_names = ['华夏成长混合', '易方达平稳增长'] # 2只基金作列名 nav_data = np.array([[1.012, 0.986], [1.018, 0.991], [1.009, 0.994]]) # 3×2净值数据 nav_df = pd.DataFrame(data=nav_data, index=nav_dates, columns=fund_names) # 组装数据框 print(nav_df) # 打印数据框 print(nav_df.values) # 取出数组形式,行列方向与数据框一致预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):
华夏成长混合 易方达平稳增长 2024-01-02 1.012 0.986 2024-01-03 1.018 0.991 2024-01-04 1.009 0.994 [[1.012 0.986] [1.018 0.991] [1.009 0.994]]注意:以上为变式代码;列表 49.1 的平台任务仍须按原始代码原样输入教学平台。
回扣主线:从 NumPy 数组创建 DataFrame 与
index/columns的对应关系见第 章节 10 章。变式任务:把本章”设置DataFrame的索引”示例中的
pd.date_range('2024-01-01', periods=5)改为按工作日频率生成(freq='B'),观察索引有何变化,并尝试用df_indexed.loc按日期切片取出其中 3 行。参考答案(点开前请先独立完成)
解题思路:
freq='B'只生成工作日(business day),跳过周六日。有一个值得注意的细节:2024-01-01 恰是周一,其后的 01-02 至 01-05 依次为周二至周五,中间没有周末,因此从 2024-01-01 出发生成 5 个工作日与逐日日历完全相同——索引”看不出变化”正是本次观察的诚实结论;把起点换到周五(如 2024-01-05),freq='B'就会跳过 01-06、01-07 两个周末日,索引变为 01-05、01-08、01-09、01-10、01-11。loc的日期切片两端都包含,可直接取出中间 3 行。# 变式脚本:工作日频率的日期索引与按标签切片 import pandas as pd # 导入pandas库 import numpy as np # 导入NumPy库 date_monday = pd.date_range('2024-01-01', periods=5, freq='B') # 周一起始的5个工作日 date_friday = pd.date_range('2024-01-05', periods=5, freq='B') # 周五起始的5个工作日 print([d.strftime('%Y-%m-%d') for d in date_monday]) # 无周末间隔,与日历逐日相同 print([d.strftime('%Y-%m-%d') for d in date_friday]) # 跳过周末,衔接下周一 df_indexed = pd.DataFrame({'收盘价': np.arange(5) + 10.0}, index=date_monday) # 以工作日为行索引 print(df_indexed.loc['2024-01-02':'2024-01-04']) # 按日期标签切片,两端都包含预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):
['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'] ['2024-01-05', '2024-01-08', '2024-01-09', '2024-01-10', '2024-01-11'] 收盘价 2024-01-02 11.0 2024-01-03 12.0 2024-01-04 13.0回扣主线:
set_index/日期索引为按标签切片打基础的论述见第 章节 10 章”设置DataFrame的索引”一节。