Pandas 常用的数据结构有两种:Series和DataFrame。其中Series是一个带有名称和索引的一维数组,而DataFrame则是用来表示多维的数组结构。
使用pandas需要频繁用到读取和写入Excel,但默认的pandas还不能读写Excel文件,需要安装xlrd(读)和xlwt(写)库才能支持Excel的读写。
为Python添加读取/写入Excel功能的命令如下:
pip install xlrd
pip install xlwt
一、Series数据结构与索引
# 导入pandas
import pandas as pd
1、Series数据结构介绍
假设我们有一系列股票的开盘价信息,那么如果在没有学习Pandas之前,我们可以用字典来表示:
stock_price_dict = {"300773":3.5, "600751":7.2,
"300405":12.6, "002937":4.7, "601615":8.2}
现在我们可以使用 pandas 轻松构建 Series 数据集:
stock_seri = pd.Series([3.5, 7.2, 12.6, 4.7, 8.2],
index=["300773", "600751", "300405", "002937", "601615"],
name="Stock")
对于上面的Series数据集,有3个比较重要的属性:index
,value
,name
。index也就是索引,在Pandas里,索引不仅仅是位置序号,你也可以根据数据集特征进行自定义,比如这里的index就是股票代码。value是股票的开盘价格。name则是数据集的名称。
# 查阅索引
stock_seri.index
Out: Index(['300773', '600751', '300405', '002937', '601615'], dtype='object')
# 查阅数据值,注意,该方法返回array格式
stock_seri.value
Out: array([ 3.5, 7.2, 12.6, 4.7, 8.2])
# 查阅数据集的名称
stock_seri.name
Out: 'Stock'
2、Series的常用操作
(1)Series的索引更为方便,你可以直接传入单个索引值进行检索,或者以列表的格式传入一组值。
stock_seri["300773"]
Out: 3.5
# 传入列表进行索引,返回格式仍是pandas.core.series.Series
stock_seri[["002937", "300773", "601615"]]
Out:
002937 4.7
300773 3.5
601615 8.2
Name: Stock, dtype: float64
# 利用布尔进行索引
stock_seri[[True, False, True, False, True]]
Out:
300773 3.5
300405 12.6
601615 8.2
Name: Stock, dtype: float64
# 切片索引。要特别注意的是,对于index切片进行索引,pandas是左闭右闭的区间,这里和Python有明显不同
stock_seri["300773":"300405"]
Out:
300773 3.5
600751 7.2
300405 12.6
Name: Stock, dtype: float64
(2)Series的运算
Numpy常用的运算,在Series里也是适用的。
# 筛选出开盘价在8以上的个股
stock_seri[stock_seri>8]
Out: 300405 12.6
601615 8.2
Name: Stock, dtype: float64
# 计算个股的双倍价格
stock_seri * 2
Out:
300773 7.0
600751 14.4
300405 25.2
002937 9.4
601615 16.4
Name: Stock, dtype: float64
# 计算股票池的均价
import numpy as np
np.average(stock_seri)
Out: 7.239999999999999
(3)查看Series数据集中是否有空值:
# 查看空值,空值的位置返回True
stock_seri.isnull()
Out:
300773 False
600751 False
300405 False
002937 False
601615 False
Name: Stock, dtype: bool
# 查看空值,空值的位置返回False
stock_seri.notnull()
Out:
300773 True
600751 True
300405 True
002937 True
601615 True
Name: Stock, dtype: bool
(4)Series的索引、更新数据也可以通过直接赋值的方式显式修改。
# 修改index
stock_seri.index = ["拉卡拉", "海航科技", "科隆股份", "兴瑞科技", "明阳智能"]
stock_seri
Out:
拉卡拉 3.5
海航科技 7.2
科隆股份 12.6
兴瑞科技 4.7
明阳智能 8.2
Name: Stock, dtype: float64
# 更新兴瑞科技的股票价格
stock_seri["兴瑞科技"] = 6.8
stock_seri
Out:
拉卡拉 3.5
海航科技 7.2
科隆股份 12.6
兴瑞科技 6.8
明阳智能 8.2
Name: Stock, dtype: float64
(5)如果数据被存放在字典中,也可以通过字典来创建Series,这里利用本节开篇的字典来创建一个股票池。
# 通过字典创造Series没有name属性
pd.Series(stock_price_dict)
Out:
300773 3.5
600751 7.2
300405 12.6
002937 4.7
601615 8.2
dtype: float64
二、DataFrame数据结构与索引
DataFrame是Series在水平方向的扩展,是一个多列表格型的数据结构。其创建过程和Series相比非常类似。
# 传入array类型,生成一个DataFrame数据结构
import numpy as np
frame0 = pd.DataFrame(np.arange(6).reshape(2,3),
index=[2000, 2001], columns=["A", "B", "C"])
frame0
Out:
A B C
2000 0 1 2
2001 3 4 5
或者也可以利用字典格式,生成DataFrame数据结构。
# 利用字典生成DataFrame
data = {"A":[0, 3], "B":[1, 4], "C":[2, 5]}
pd.DataFrame(data, index=[2000, 2001])
Out:
A B C
2000 0 1 2
2001 3 4 5
从上面的例子看,相比较Series,DataFrame多了列索引,也就意味着对DataFrame的索引更加灵活。
# 用中括号传入对应的列名,可以进行列索引。索引的结果为Series格式
frame0["A"]
Out:
2000 0
2001 3
Name: A, dtype: int32
# 同时对多列索引,需要以列表的形式传入序列
frame0[["A", "B"]]
Out:
A B
2000 0 1
2001 3 4
DataFrame索引的索引则稍有区别,也是学习的重点之一。DataFrame的索引包括行索引与列索引,但是因为DataFrame的行和列均有实体的标签名(相较于Numpy,其只有位置索引),所以我们可以通过两种方式进行索引,分别是标签索引和位置索引。
1、loc 标签索引
Pandas自带的loc方法,通过具体的标签名字来索引行或者列。
# 选择索引为2000的行
frame0.loc[2000]
Out:
A 0
B 1
C 2
Name: 2000, dtype: int32
# 选择“A”列
frame0.loc[:,"A"]
Out:
2000 0
2001 3
Name: A, dtype: int32
# 选择索引为2001,BC列的元素
# 在pandas中,利用标签名进行索引,遵从左闭右闭的区间,这点和位置索引不一样
frame0.loc[2001, "B":"C"]
Out:
B 4
C 5
Name: 2001, dtype: int32
在loc函数中,可以传入一组后者两组标签名参数,第一组参数表示index,第二组则用来表征columns。
2、iloc函数
Pandas自带的iloc方法,通过位置来索引行或者列,索引规则和Numpy的切片索引非常相似。
# 通过位置,选择索引为2000的行
frame0.iloc[0]
Out:
A 0
B 1
C 2
Name: 2000, dtype: int32
# 通过位置,选择“A”列
frame0.iloc[:,0]
Out:
2000 0
2001 3
Name: A, dtype: int32
# 通过位置,选择索引为2001,BC列的元素
# 这里要区分开来,涉及到位置切片,仍然为左闭右开的规则
frame0.iloc[1, 1:]
Out:
B 4
C 5
Name: 2001, dtype: int32
在iloc函数中,可以传入一组后者两组位置参数,第一组参数表示index,第二组则用来表征columns。
3、索引对象初窥
(1)DataFrame的行
在上面的案例中,我们在创建数据结构的过程中,都显式地定义了index
的值(也就是行索引),这里我们就来探究一下index
的基本特性。
# index对象可以像列表一样被灵活切片
frame0.index[:1]
Out: Int64Index([2000], dtype='int64')
# 但是index对象是不可以被修改的。
# 如果用户希望更改数据集的索引,要么显式的重新定义index(就像上文,显式地更改Series的index)。
# 要么用reindex的方式,为数据集构造一个新的index对象
frame0.reindex([2000, 2001, 2002])
Out:
A B C
2000 0.0 1.0 2.0
2001 3.0 4.0 5.0
2002 NaN NaN NaN
# 可以看到,reindex的方式,会继承原先的索引,如果有新增的索引项,那么会自动填充空值。
# 也可以增加fill_value属性,自动填充其他值。
frame0.reindex([2000, 2001, 2002], fill_value=20)
Out:
A B C
2000 0 1 2
2001 3 4 5
2002 20 20 20
(2)DataFrame的列
那列索引呢?
# 列索引的基本格式和行索引一直,也是Pandas自带的Index格式
frame0.columns
Out: Index(['A', 'B', 'C'], dtype='object')
如果要修改列名,有2种方法。一种是利用rename
函数,另一种则是显式地重新指定。
# 方法一:利用rename函数
frame0.rename(columns = {"A": "col_01", "B": "col_02", "C": "col_03"})
Out:
col_01 col_02 col_03
2000 0 1 2
2001 3 4 5
# 方法二:重新指定
frame0.columns = ["col_01", "col_02", "col_03"]
frame0
Out:
col_01 col_02 col_03
2000 0 1 2
2001 3 4 5
总结
有了Numpy的基础,入门Pandas还是很友好的。Pandas最重要的两种数据结构为Series
和DataFrame
,其中Series可以理解为一维的数据表格。
无论是Series还是DataFrame,和array相比,最大的区别是多了标签名,包括行标签名和列标签名。因此在对Series和DataFrame索引的时候,可以灵活地选择位置索引和标签名索引,大家可以根据习惯自由选择,精通一种、熟悉另一种即可。
网友评论