「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」。
1.pandas数据结构介绍
常用的工具数据结构:。
1.1 Series
Series是一种一维的数组型对象,它包含了一个值序列(与NumPy中的类型相似),并且包含了数据标签,称为索引(index)。
- 默认生成的索引是从 0 到 N-1;
- 可以通过values属性和index属性分别获得Series对象的值和索引;
- 通常需要创建一个索引序列,用标签标识每个数据点;
- 与NumPy的数组相比,Series可以用标签索引数据;
- pd.Series(字典):直接根据字典生成一个Series,产生的Series索引将是排序好的字典键,如果想要指定索引的顺序,可以用:pd.Series(data, index = 索引列表)的形式创建Series数据;
- pandas标记缺失值或NA值的方式:NaN(not a number);
- Series有一个非常有用的特性:自动对齐索引;
- Series对象自身和其索引都有 name 属性;
- Series的索引可以通过按位置赋值的方式进行改变。
1.2 DataFrame
DataFrame表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引。
- 常用的构建DataFrame的方式:利用包含等长度列表或NumPy数组的字典来形成DataFrame;
- 对于大型DataFrame,head方法将只会选出头部的五行;
- 如果指定了列的顺序,DataFrame的列将会按照指定顺序排列:pd.DataFrame(data, columns=[列序列]);
- 如果传的列不在字典里面,将会在结果中出现缺失值;
- dataFrame[column]或dataFrame.column取特定列:返回的数据类型是Series;
- dataFrame.loc[row]取特定的行;
- 列的引用是可以修改的,当将列表或数组赋值给一个列时,值的长度必须和DataFrame的长度相匹配。如果将Series赋值给一列时,Series的索引将会按照DataFrame的索引重新排列,并在空缺的地方补充缺失值(NaN);
- 从DataFrame中选取的列是数据的视图,而不是拷贝。因此,对Series的修改会映射到DataFrame中,如果需要复制,需显式地使用Series的copy方法;
- 利用嵌套字典也可以创建DataFrame数据,pandas会将字典的键作为列,将内部字典的键作为行索引;
- 包含Series的字典也可以用于构造DataFrame;
- 和Series类似,DataFrame的values属性会将包含在DataFrame中的数据以二位ndarray的形式返回,如果DataFrame的列是不同的dtypes,则values的dtype会自动选择适合所有列的类型。
DataFrame构造函数的有效输入:
| 类型 | 注释 |
|---|---|
| 2D ndarray | 数据的矩阵,行和列的标签是可选参数 |
| 数组、列表和元组构成的字典 | 每个序列成为DataFrame的一列,所有的序列必须长度相等 |
| Numpy结构化/记录化数组 | 与数组构成的字典一致 |
| Series构成的字典 | 每个值成为一列,每个Series的索引联合起来形成结果的行索引,也可以显式地传递索引 |
| 字典构成的字典 | 每一个内部字典成为一列,键联合起来形成结果的行索引 |
| 字典或Series构成的列表 | 列表中的一个元素形成DataFrame的一行,字典键或Series索引联合起来形成DataFrame的列标签 |
| 列表或元组构成的列表 | 与2D ndarray的情况一致 |
| 其他DataFrame | 如果不显示传递索引,则会使用原DataFrame的索引 |
| Numpy MaskedArray | 与2D ndarray的情况类似,但隐蔽值会在结果DataFrame中成为NA/缺失值 |
1.3 索引对象
pandas中的索引对象是用于存储轴标签和其他元数据的(例如轴名称或标签)。在构造Series或DataFrame时,所使用的任意数组或标签序列都可以在内部转换成索引对象。
- 索引对象是不可变的,因此用户无法修改索引对象;
- 除了类似数组,索引对象也像一个固定大小的集合;
- 与Python集合不同,pandas索引对象可以包含重复的标签。
一些索引对象的方法和属性
| 方法 | 描述 |
|---|---|
| append | 将额外的索引对象粘贴到原索引后,产生一个新的索引 |
| difference | 计算两个索引的差集 |
| intersection | 计算两个索引的交集 |
| union | 计算两个索引的并集 |
| isin | 计算表示每一个值是否在传值容器中的布尔数组 |
| delete | 将位置i的元素删除,并产生新的索引 |
| drop | 根据传参删除置顶索引值,并产生新的索引 |
| insert | 在位置i插入元素,并产生新的索引 |
| is_monotonic | 如果索引序列递增则返回True |
| is_unique | 如果索引序列唯一则返回True |
| unique | 计算索引的唯一值序列 |
2.基本功能
2.1 重建索引
reindex方法是pandas对象的重要方法,该方法用于创建一个符合新索引的新对象。
- Series调用reindex方法时,会将数据按照新的索引进行排列,如果某个索引值之前并不存在,则会引入缺失值;
- 对于顺序序列(比如时间序列),在重建索引时可能会需要进行插值或填值。method可选参数允许使用诸如ffill等方法在重建索引时插值,ffill方法会将值前向填充(前面缺失值的会自动填充NaN);
- 在DataFrame中,reindex可以改变行索引、列索引,也可以同时改变二者,当仅传入一个序列时,结果中的行会重建索引;
- 列可以使用columns关键字重建索引(frame.reindex(columns = 新的列序列));
- 可以使用loc进行更为简介的标签索引:frame.loc[行索引, 列索引]。
reindex方法的参数
| 参数 | 描述 |
|---|---|
| index | 新建作为索引的序列,可以是索引实例或任意其他序列型Python数据结构,索引使用时无须复制 |
| method | 插值方式;'ffill'为前向填充,而'bfill'是后向填充 |
| fill_value | 通过重新索引引入缺失数据时使用的替代值 |
| limit | 当前向或后向填充时,所需填充的最大尺寸间隙(以元素数量) |
| tolerance | 当前向或后向填充时,所需填充的不精确匹配下的最大尺寸间隙(以绝对数字距离) |
| level | 匹配MultiIndex级别的简单索引;否则选择子集 |
| copy | 如果为True,即使新索引等于旧索引,也总是复制底层数据;如果是False,则在索引相同时不要复制数据 |
2.2 轴向上删除条目
drop方法会返回一个含有指示值或轴向上删除值的新对象。
- 在DataFrame中,索引值可以从轴向上删除;
- 在调用drop时使用标签序列会根据行标签删除值(轴0);
- 可以通过传递axis = 1或axis = 'columns'来从列中删除值;
- 很多函数,例如drop,会修改Series或DataFrame的尺寸或形状,这些方法直接操作原对象而不返回新对象(需要设置参数:inplace = True,这代表会清除被删除的数据(frame.drop([index], inplace = True))。
2.3 索引、选择和过滤
Series的索引(obj[...])与NumPy数组索引的功能类似,只不过Series的索引值可以不仅仅是整数(还可以是标量、切片、列表、布尔表达式等等)。
- 普通的Python切片中是不包含尾部的,Series的切片与之不同(包含尾部);
- 使用单个值或序列,可以从DataFrame中索引出一个或多个列;
- 还可以使用布尔值DataFrame进行索引,布尔值DataFrame可以是对标量值进行比较产生的:data[data < 5](把数据小于5的值筛选出来)。
2.4 使用loc和iloc选择数据
loc和iloc允许使用轴标签(loc)或整数标签(iloc)以NumPy风格的语法从DataFrame中选出数组的行和列的子集。
- 除了单个标签或标签列表之外,索引功能还可以用于切片。
DataFrame索引选项(下方df代表DataFrame)
| 类型 | 描述 |
|---|---|
| df[val] | 从DataFrame中选择单列或列序列;特殊情况的便利:布尔数组(过滤行),切片(切片行)或布尔值DataFrame(根据某些标准设置的值) |
| 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.5 算术和数据对齐
在pandas中,不用索引的对象之间是可以有算术行为的,当将对象相加时,如果存在某个索引对不相同,则返回结果的索引将是索引对的并集,这个特性类似于数7据库里面的自动外连接。
- Series相加:没有交叠的位置上,内部数据对齐会产生缺失值(NaN),DataFrame亦然;
- 如果将两个行或列完全不同的DataFrame对象相加,结果将全部为空;
- 如果想补充缺失值,可以在算术方法里面带上参数:fill_value;
- 当Series或DataFrame重建索引时,也可以指定一个fill_value去填充缺失值;
- 默认情况下,DataFrame和Series的数学操作中会将Series的索引和DataFrame的列进行匹配,并广播到各行;
- 如果一个索引值不在DataFrame的列中,也不在Series的索引中,则对象会重建索引并形成联合;
- 如果想改成在列上进行广播,在行上匹配,需要使用算数算法,且加上参数:axis = 0 或 axis = 'index'。
灵活算术方法(以r开头的副本方法的参数是翻转的,比如 1/df 等价于 df.rdiv(1))
| 方法 | 描述 |
|---|---|
| add,radd | 加法(+) |
| sub,rsub | 减法(-) |
| div,rdiv | 除法(/) |
| floordiv, rfloordiv | 整除(//) |
| mul, rmul | 乘法(*) |
| pow,rpow | 幂次方(**) |
2.6 函数应用和映射
- 将函数应用到一行或一列的一维数组上,可以使用apply方法:frame.apply(f);
- 传递给apply的函数并不一定要返回一个标量值,也可以返回带有多个值的Series;
- 逐元素的Python函数也可以使用,可以使用applymap方法:frame.applymap(f)。
- 使用applymap作为函数名是因为Series有map方法,可以将一个逐元素的函数应用到Series上。
2.7 排序和排名
根据某些准则对数据集进行排序是另外一个重要的内建操作。
- 如果需要按行或列索引进行字典型排序,需要使用sort_index方法,该方法返回一个新的、排序好的对象(参数axis控制行、列,参数ascending控制升/降序);
- 如果需要根据Series的值进行排序,使用sort_value方法,默认情况下,所有缺失值都会被排序至Series的尾部;
- 对DataFrame排序时,可以使用一列或多列作为排序键,需要传递一个或多个列给sort_value的可选参数by:frame.sort_value(by = [序列])。
排名是指对数组从1到有效数据点总数分配名次的操作。Series和DataFrame的rank方法是实现排名的方法,默认情况下,rank通过将平均排名分配到每个组来打破平级关系。
[in]
obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
[out]
obj
0 7
1 -5
2 7
3 4
4 2
5 0
6 4
dtype: int64
[in]
obj.rank()
[out]
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
上例中为什么第0个数据7的排名是6.5?因为原数据中有两个7,分别排名6、7名,所以取均值6.5。
- 排名也可以根据他们在数据中的观察顺序进行分配:设置参数method = 'first'即可;
- 可以按降序排名:设置ascending = False即可;
- 可以按行或列计算排名:设置参数axis = columns | index。
排名中的平级关系打破方法
| 方法 | 描述 |
|---|---|
| 'average' | 默认:在每个组中分配平均排名 |
| 'min' | 对整个组使用最小排名 |
| 'max' | 对整个组使用最大排名 |
| 'first' | 按照值在数据中出现的次序分配排名 |
| 'dense' | 类似于method = 'min',但组间排名总是增加11,而不是一个组中的相等元素的数量 |
3.描述性统计的概述与计算
pandas对象装配了一个常用数学、统计学方法的集合。其中大部分属于归约或汇总统计的类别,这些方法从DataFrame的行或列中抽取一个Series或一系列值的单个值(如总和或平均值)。与NumPy数组类似方法相比,它们内建了处理缺失值的功能。
- 除非整个切片上都是NA,否则NA值是被自动排除的,可以通过禁用skipna来实现不排除NA值:skipna = False。
归约方法可选参数
| 方法 | 描述 |
|---|---|
| axis | 归约轴,0为行向,1位列向 |
| skipna | 排除缺失值,默认为True |
| level | 如果轴是多层索引的(MultiIndex),该参数可以缩减分组层级 |
描述性统计和汇总统计
| 方法 | 描述 |
|---|---|
| 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的、按索引对齐的值的相关性,相应的,cov计算的是协方差;
- DataFrame的corr和cov方法会分别以DataFrame的形式返回相关性和协方差矩阵;
- 使用DataFrame的corrwith方法,可以计算出DataFrame中的行或列与另一个序列或DataFrame的相关性。该方法传入一个Series时,会返回一个含有为每列计算相关性值的Series。
3.2 唯一值、计数和成员属性
-
unique:唯一值,可以用unique.sort()方法对结果进行排序;
-
value_counts:计算Series包含的值的个数,返回的Series会按照数量降序排列,可以用于任意数组或序列;
-
isin:执行向量化的成员属性检查,还可以将数据集以Series或DataFrame一列的形式过滤为数据集的值子集;
-
与isin相关的Index.get_indexer方法,可以提供一个索引数组,这个索引数组可以将可能非唯一值数组转换为另一个唯一值数组。
[in] to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a']) unique_vals = pd.Series(['c', 'b', 'a']) pd.Index(unique_vals).get_indexer(to_match) [out] array([0, 2, 1, 1, 0, 2], dtype=int64)
唯一值、技术和集合成员属性方法
| 方法 | 描述 |
|---|---|
| isin | 计算表征Series中每个值是否包含于传入序列的布尔值数组 |
| match | 计算数组中每个值的整数索引,形成一个唯一值数组。有助于数据对齐和join类型的操作 |
| unique | 计算Series值中的唯一值数组,按照观察顺序返回 |
| value_counts | 返回一个Series,索引是唯一值序列,值是计数个数,按照个数降序排列 |