pandas 采用了很多 NumPy 的代码风格,但最大的不同在于 pandas 是用来处理表格型或异质性数据的,而 NumPy 更适合处理同质型的数值类数组数据
1. pandas 数据结构介绍
1.1 Series
- Series 是一种一维的数组型对象,包含了一个值序列,并且包含了数据标签(索引 index);
- 通过 Series.values 和 Series.index 属性分别获得 Series 对象的值和索引;
obj = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
values = obj.values
index = obj.index
- 可以使用索引标签来选择数据
- 也可以认为 Series 是一个长度固定且有序的字典,使用字典生成一个 Series:
dic = {'a': 1, 'b': 2, 'c': 3}
obj = pd.Series(dic)
- 使用 isnull 和 notnull 函数检查缺失数据,返回值为布尔型的 Series,同时 isnull 和 notnull 也是 Series 的实例方法:
pd.isnull(obj)
pd.notnull(obj)
obj.isnull()
obj.notnull()
- Series 对象自身及其索引都有name属性:
obj.name = 'numbers'
obj.index.name = 'letters'
- Series 的索引可以通过按位置赋值的方式进行改变:
obj.index = ['c', 'b', 'a']
1.2 DataFrame
- DataFrame 表示的是矩阵的数据表;
- DataFrame 的每一列可以是不同的值类型;
- DataFrame 既有行索引也有列索引,可以被视为一个共享相同索引的 Series 的字典;
- 利用包含等长度列表或 NumPy 数组的字典来生成 DataFrame:
data = {'a': [1, 2, 3, 4, 5],
'b': ['one', 'two', 'three', 'four', 'five'],
'c': [1., 2., 3., 4., 5.]}
frame = pd.DataFrame(data, [index=[1, 2, 3, 4, 5], [columns=['b', 'c', 'a']])
- 使用 frame.head() 方法可以只选出头部的 5 行;
- DataFrame 中的一列,可以按字典型标记或属性那样检索为 Series:
frame['a'] == frame.a
- 行可以通过特殊属性 loc 进行选取;
frame.loc(1)
frame.iloc(0)
- 列的引用是可以修改的;当将列表或数组赋值给一个列时,值的长度必须和 DataFrame 的长度相匹配;
data['c'] = np.arange(5)
- 将 Series 赋值给一列时,Series 的索引将会按照 DataFrame 的索引重新排列,并在空缺的地方填充缺失值;
- 如果被赋值的列不存在,则会生成一个新的列;del 关键字可以像在字典中那样对 DataFrame 删除列:
frame['d'] = 10
del frame['d']
- 从 DataFrame 中选取的列是数据的视图,而不是拷贝,因此对 Series 的修改会映射到 DataFrame 中,若需要复制,则需要显式地使用 copy 方法;
- 其他常用的数据形式:
a. 包含字典的嵌套字典:使用字典的键作为列,内部字典的键作为行索引;
b. 包含 Series 的字典 - DataFrame 的 values 属性会将包含在 DataFrame 中的数据以二维 ndarray 的形式返回;
- DataFrame 构造函数的有效输入
类型 | 注释 |
---|
2D ndarray | 数据的矩阵,行和列的标签是可选参数 |
数组、列表和元组构成的字典 | 每个序列成为 DataFrame 的一列,所有的序列必须长度相等 |
NumPy 结构化/记录化数组 | 与数组构成的字典一致 |
字典构成的字典 | 每一个内部字典称为一列,键联合起来形成结果的行索引 |
字典或 Series 构成的列表 | 列表中的一个元素形成 DataFrame 的一行,字典键或 Series 索引联合起来形成 DataFrame 的列标签 |
列表或元组构成的列表 | 与 2D ndarray 的情况一致 |
其他 DataFrame | 如果不显示传递索引,则会使用原 DataFrame 的索引 |
NumPy MaskedArray | 与 2D ndarray 的情况类似,但隐蔽值会在结果 DataFrame 中称为 NA 值 |
1.3 索引对象
- 索引对象是用于存储轴标签和其他元数据的(轴名称或标签);
- 索引对象是不可变的,可在多种数据结构中分析索引对象;
- 一些索引对象的方法和属性:
方法 | 描述 |
---|
append | 将额外的索引对象粘贴到原索引后,产生一个新的索引 |
difference | 计算两个索引的差集 |
intersection | 计算两个索引的交集 |
union | 计算两个索引的并集 |
isin | 计算表示每一个值是否在传值容器中的布尔数组 |
delete | 将位置 i 的元素删除,并产生新的索引 |
drop | 根据传参删除指定索引值,并产生新的索引 |
insert | 在位置 i 插入元素,并产生新的索引 |
is_monotonic | 如果索引序列递增则返回 True |
is_unique | 如果索引序列唯一则返回 True |
unique | 计算索引的唯一值序列 |
2. 基本功能
2.1 重建索引: reindex
reindex 方法的参数:
参数 | 描述 |
---|
index(行)/columns(列) | 新建作为索引的序列,可以是索引实例或任意其他序列型 Python 数据结构,索引使用时无序复制 |
method | 插值方式,‘ffill’ 为前向填充,而 ‘bfill’ 是后向填充 |
fill_value | 通过重新索引引入缺失数据时使用的替代值 |
limit | 当前向或后向填充时,所需填充的最大尺寸间隙(以元素数量) |
tolerance | 当前向或后向填充时,所需填充的不精确匹配下的最大尺寸间隙(以绝对数字距离) |
level | 匹配 MultiIndex 级别的简单索引,否则选择子集 |
copy | 如果为 True,即使新索引等于旧索引,也总是复制底层数据;如果是 False,则在索引相同时不要复制数据 |
2.2 轴向上删除条目: drop
- drop 方法会返回一个删除指定条目的新对象;
- 在 DataFrame 中,默认删除行标签上的值(轴 0),使用 axis=1 或 axis=‘columns’ 删除列上的值;
- inplace=True 属性会清除被删除的数据(修改原对象)
2.3 索引、选择与过滤
- Series 使用整数索引时与 NumPy 数组一致,使用索引名称作为索引值时,切片是包含尾部的;
- 使用切片修改值时会修改原对象的相应的部分;
- DataFrame 索引选项:
类型 | 描述 |
---|
df[‘one’] | 从 DataFrame 中选择单列或者列序列 |
df[df[‘one’] > 0] | 过滤行,选择 one 列中大于 0 的行; |
df[:2] | 切片行,选择0~1行 |
df[df > 0] | 根据逻辑表达式进行索引 |
df.loc[val] | 根据标签选择 DataFrame 的单行或者多行 |
df.loc[:, val] | 根据标签选择单列或多列 |
df.loc[val1, val2] | 同时选择行和列中的一部分 |
df.iloc[where] | 根据整数位置选择单行或多行 |
df.iloc[:, where] | 根据整数位置选择单列或多列 |
df.iloc[where_i, where_j] | 证据整数位置选择行和列 |
df .at[label_i, label_j] | 根据行、列标签选择单个标量值 |
df.iat[i, j] | 根据行、列整数位置选择单个标量值 |
reindex方法 | 通过标签选择行或列 |
get_value, set_value方法 | 根据行和列的标签设置单个值 |
2.4 整数索引
对于 pandas 对象来说,当轴索引为整数时,直接使用整数索引容易出现错误,因为无法推断用户是使用标签索引还是位置索引,因此对于轴索引为整数的 pandas 对象,最好使用 loc(用于标签)或 iloc(用于整数)
2.5 算术和数据对齐
- 将对象相加时,如果存在某个索引对不同,则返回结果的索引将是索引对的并集,没有交叠的标签位置上,会使用 NaN 填充;对于 DataFrame,行和列都会执行对齐;
- 指定特殊的填充值:可以在使用算术方法的时候,添加 fill_value 参数
- 灵活算术方法(带 r 的副本方法的参数是反转的):
方法 | 描述 |
---|
add, radd | 加法 |
sub, rsub | 减法 |
div, rdiv | 除法 |
floordiv, rfloordiv | 整除 |
mul, rmul | 乘法 |
pow, rpow | 幂次方 |
- DataFrame 和 Series 间的操作:类似于 NumPy 中不同维度数组间的操作(广播机制),默认情况下会将 Series 的索引和 DataFrame 的列进行匹配,并广播到各行;通过在算术方法中传递 axis=‘index’ or axis=0 来进行行匹配,并广播到各列;
2.6 函数应用和映射
- NumPy 的通用函数(逐元素数组方法)对 pandas 对象也有效;
- 使用 apply 方法将函数应用到一行或一列的一维数组上(默认对每列调用一次,即保留列索引,“消灭”行,使用 axis=‘columns’ 来对每行调用,即保留行索引,“消灭”列);
- apply 函数也可以返回带有多个值的 Series;
- 使用 applymap 方法对 DataFrame 执行逐元素的函数,Series 对象使用 map 方法;
2.7 排序和排名
- 按行或列索引进行字典型排序:
frame.sort_index(axis=1, ascending=False)
- 根据 Series 的值进行排序:
series.sort_values(ascending=False)
- 根据 DataFrame 的值进行排序:
frame.sort_values(by='a')
frame.sort_values(by=['a', 'b'])
- 排序返回的都是新的对象;
- 排名是指对数组从1到有效数据点总数分配名次的操作:
series.rank(ascending=False, method='first')
frame.rank(axis='columns')
平级的处理方法:
方法 | 描述 |
---|
‘average’ | 默认:在每个组中分配平均排名 |
‘min’ | 对整个组使用最小排名(数字向下取) |
‘max’ | 对整个组使用最大排名(数字向上取) |
‘first’ | 按照值在数据中出现的次序分配排名 |
‘dense’ | 类似于 method=‘min’,但组间排名总是增加1,而不是一个组中的相等元素的数量 |
2.8 含有重复标签的轴索引
- 索引的 is_unique 属性可以检查是否含有重复标签;
- Series 的重复标签的数据选择返回一个序列,而唯一标签的数据选择返回一个标量;
- 相同逻辑可以拓展到 DataFrame 中
3. 描述性统计的概述与计算
- 归约方法(如 sum):
可选参数 | 描述 |
---|
axis | 指定归约轴,0 为行(“消灭”行索引,每列上的各行执行归约方法),1 为列 |
skipna | 排除缺失值,默认为 True,除非整行或整列都是 NA 值 |
level | 如果轴是多层索引的,该参数可以缩减分组层级 |
- 描述性统计和汇总统计
方法 | 描述 |
---|
count | 非 NA 值的个数 |
describe | 计算 Series 或 DataFrame 各列的汇总统计集合 |
min, max | 计算最小值,最大值 |
argmin, argmax | 分别计算最小值、最大值所在的索引位置(整数) |
idxmin, idxmax | 分别计算最小值或最大值所在的索引标签 |
quantile | 计算样本的从 0 到 1 间的分位数 |
sum | 加和 |
mean | 均值 |
median | 中位数(50%分位数) |
mad | 平均值的平均绝对偏差 |
prod | 所有值的积 |
var | 值的样本方差 |
std | 值的样本标准差 |
skew | 样本偏度(第三时刻)值 |
kurt | 样本峰度(第四时刻)值 |
cumsum | 累计值 |
cummin, cummax | 累计值的最小值或最大值 |
cumprod | 值的累计积 |
diff | 计算第一个算术差值(对时间序列有用) |
pct_change | 计算百分比 |
3.1 相关性和协方差
- Series 的 corr 方法计算两个 Series 中重叠的、非 NA 的、按索引对齐的值的相关性;
- Series 的 cov 方法计算的是协方差;
series1.corr(series2)
series1.cov(series2)
- DataFrame 的 corr 和 cov 方法分别以 DataFrame 的形式返回相关性和协方差矩阵
df.corr()
df.cov()
- DataFrame 的 corrwith 方法可以计算出 DataFrame 中的行或列于另一个序列或 DataFrame 的相关性
df.corrwith(series, axis='columns')
3.2 唯一值、计数和成员属性
- 唯一值:
series.unique()
- 计数:
series.value_counts()
pd.value_counts(series.values, sort=False)
- 向量化的成员属性检查:
series.isin(array)