Advertisement

Python数据科学:Pandas数据处理教程

阅读量:

Pandas对象简介

Pandas的Series对象

Pandas 的 Series 实体是一个带索引数据构成的一维数组,在该对象中存储的数据与其对应的索引是紧密结合在一起的。该对象的values属性用于获取数据的具体值,在实际应用中其values属性的值类似于NumPy数组这一特性常常被利用到;而其index属性返回的是一个pd.Index类型的对象,在处理标签引用时非常关键。

Serise是通用的NumPy数组

NumPy数组通过隐式的整数索引来进行数值获取,Pandas中的Series对象采用显式的索引来与数值相关联.通过明确指定的索引体系,Series对象展现出更强大的功能.例如, 索引不仅限于整数,还可以指定为任何所需的类型.

Series是一种特殊的Python字典结构体
从功能上讲,Pandas的Series对象类似于一种带有类型约束的高级字典。
在数据结构中,字典是一种将键映射到值的集合的数据模型。
而Series对象其实是一种通过类型键管理一组类型一致的值的数据容器。
数据类型的特性类似于NumPy数组,在特定操作中通过优化代码路径提升了性能。
与普通Python字典相比,在某些运算中Pandas Series表现出更高的效率和性能优势。

熟悉几种创建 Pandas 的 Series 对象的方法
通常采用以下形式:
pd.Series(data, index=index)
其中index参数是一个可选参数,默认情况下若未指定则会生成从0开始的整数序列;data参数支持多种数据类型;当data为列表或NumPy数组时,默认情况下index会被视为从0开始的整数序列;当data为标量值时,默认情况下该标量值会被复制到每个索引位置上;如果data是以字典形式给出,则默认情况下其键会被排序作为新的索引;

Pandas的DataFrame对象

DataFrame 可以被视为通用的 NumPy 数组
如果将 Series 类比为带灵活索引的一维数组,则 DataFrame 可以被看作是一种既有灵活行索引又有灵活列名的二维数组。类似于你可以将二维数组视为有序排列的一维数组一样,在这种类比下你也可以将 DataFrame 视为有序排列的若干个 Series 对象;这里的"排列"指的是它们共享相同的索引标签。类似于 Series 对象那样,在这种类比下你还可以看到一种有序排列的方式——即它们共享相同的索引标签

DataFrame是一种特殊的数据结构
值得注意的是,在NumPy的二维数组中使用data[0]获取到第一行;而通过data['col0']获取到的是某一列的具体数据。因此建议将DataFrame视为一个高效的数据容器。尽管这种视角在特定场景下非常实用,在其他情况下同样具有重要价值。

构建DataFrame对象
(1) 基于单一Series构建. DataFrame本质上是由多个Series组成的集合,因此可以通过一个Series对象来构造一个单列的DataFrame.
(2) 从包含字典的列表生成. 如果列表中的每个元素都是字典,那么Pandas会自动将这些字典转换为DataFrame,并且即使某个字典缺少某些键,Pandas也会使用NaN(非数值)来表示缺失项.
(3) 通过字典列表生成DataFrame. 这种方法允许我们灵活地定义数据结构并生成相应的表格数据.
(4) 使用NumPy二维数组构建DataFrame. 如果有一个二维NumPy数组,我们可以指定行和列索引来生成一个带有具体值的DataFrame.
(5) 借助NumPy结构化数组构建

Pandas的Index对象

Pandas 的 Index 对象具有独特的特性,在数据分析中扮演着重要角色。它既可以被视为不可变的数组形式进行操作又可以在需要时以有序集合的方式进行处理。

视Index为不可变数组
在处理过程中,我们假设 Index 类型的数据类似于静态的数组结构。
进一步分析发现,在大多数情况下 Index对象与NumPy 数组之间存在显著差异:其一, Index对象中的索引固定不变;其二,无法通过常规方式对这些索引进行调整

|

|

Series数据选择方法

Series数据选择方法

把Series视为字典结构;它与字典相似地支持键值对映射关系;该对象还支持类似字典的数据更新方式(如增加、删除或修改键值)。类似于通过添加新的键来扩展字典功能的方式,在这种情况下你也可以通过添加新的索引值来扩展Series对象以实现类似的功能

可将Series视为一维数组形式存在。
除了提供与字典相似的接口外,并支持像NumPy数组一样的高级数据选择功能。
包括但不限于:

  • 使用明确的键列表进行切片
  • 通过默认步长进行切片
  • 应用满足特定条件的数据点
  • 实现复杂的键选择机制

从0开始,左闭右开区间

Python 代码的设计原则之一是“明示性优于隐晦性”。通过采用 loc 和 iloc 这两个概念来提高代码的可维护性和可读性。

DataFrame数据选择方法

将 DataFrame 视为字典结构,
第一种类比是将 DataFrame 视为由若干 Series 对象构成的一个复合数据容器。
每个 Series 都代表 DataFrame 中的一列,
通过按键的方式访问数据:
data[‘area’]
同样地,
我们可以使用属性访问纯字符串类型的列:
data.area

虽然属性数据形式的选择策略虽然便捷但并不适用于所有场景如果列名不是单一的纯字符串类型或者与 DataFrame 内置函数名称一致则无法使用属性索引法例如在 pandas 中 DataFrame 具备 pop() 方法当执行 data.pop()操作时实际上会返回的是该方法本身而非对应的列数据

将DataFrame视为一个增强版的二维数组模型;可以通过values属性获取每一行的数据内容;支持行列转换的操作功能;使用字典形式获取列数据将导致我们在将其视为NumPy数组时失去部分功能;特别地,在利用DataFrame中的单个行索引获取一行数据时需要注意的是 获取一列数据则需通过传递相应的列索引来完成

当我们需要处理数组形式的数据时,在无法直接使用NumPy方法的情况下就必须采用Pandas中的三个定位工具:loc、iloc和ix了。其中iloc定位器类似于直接操作NumPy数组的方式访问Pandas底层的数据(Python隐式的索引系统),并且能够保持DataFrame行标签和列标签在结果中自然地保留下来。
data.iloc[:3, :2]
此外我们还可以使用loc indexer来引用特定的行标签与列标签组合如data.loc[:'Illinois', :'pop']。
最后还需要掌握ix定位器这种混合效果的操作方式:
data.ix[:3, :'pop']

3.其他取值方法
首先,在处理单一标签时采用列的方式,在涉及多标签时则采用行切片;即使不使用索引号也可通过直接基于行号的方式来完成对应的操作;同样地,在进行掩码操作时其过滤处理同样可基于每条记录执行,并无需借助loc切片即可完成数据筛选;

Pandas数值运算方法

但是Pandas也提供了许多高效的技术手段:对于单目运算(例如函数及其三角函数),这些通用函数在输出结果中会保留索引与列标签;而对于双目运算(如加法与乘法),Pandas在执行通用函数时会自动对齐索引以完成计算操作。这也就意味着,在处理数据存储与合并来自不同来源的数据——这两处容易出错的地方——成为了Pandas的核心优势所在

通用函数:保留索引

通用函数:索引对齐

当在对操作的两个 Series 或 DataFrame 对象上执行二元运算时, Pandas 会自动对齐参与运算的对象的索引. 当你处理不完整或缺失数据的时候, 这一特性使得处理不完整数据变得更加便捷.

在Series对象中进行索引配准时

如果使用NaN值并非我们的预期结果,则可以选择适当的目标类来替代运算符。例如,在Python中使用A.add(B)等同于A+B操作;也可以通过参数设置来自定义处理缺失的数据:A.add(B, fill_value=0)

在计算两个 DataFrame 时,在公共(联合)列中也会遵循相同的索引对齐规则。
对于 Series 对象,请通过运算符方法中的 fill_value 参数来自定义缺失值。
为了实现这一目标,在A中计算所有元素的平均值得到fill变量:
fill = A.stack().mean()
A.add(B, fill_value=fill)

在这里插入图片描述

通用函数:DataFrame与Series的运算

DataFrame 和 Series 的运算规律遵循相同的规律,在 NumPy 中二维数组与一维数组之间的运算也遵循相同的规律。基于广播机制,在 NumPy 中对二维数组减去自身某一行的数据时会按行计算。通常情况下,在 Pandas 中也是按照照行进行计算;如果希望按照列进行计算,则需要使用之前介绍的运算符方法,并通过 axis 参数指定。

处理缺失值

选择处理缺失值的方法

在数据表或 DataFrame 中存在多种识别缺失值的手段。通常采用以下两种方式之一:一种方式是使用全局遮罩来标识缺失值;另一种方式则是引入一个特定的占位符(称为 senti...)来表示缺失数据。

在掩膜法中,掩膜可能表现为与原始数据数组维度一致的完整布尔类型数组,或者以二进制位(0或1)作为局部状态标记.其标签值可能以具体数据形式呈现(如以-9999标记整数缺失),或者采用个别形式进行特殊标识.此外,标签值还可能设定为更为广泛的代表值,例如将NaN(非数值)作为浮点型数据中的缺失标志.值得注意的是,尽管NaN在数值处理中具有特殊意义,但其应用通常仅限于数值型数据处理

Pandas的缺失值

综合考量各方案的优势与不足后可知,Pandas最后决定采用标签机制来标记缺失数据,该做法涵盖了两种常见的数据缺失表示方式:浮点型数据中的NaN标记与Python中的None对象.

1.None:Python对象类型的缺失值
由于 None 作为一个 Python 对象, 因此无法作为 NumPy/Pandas 任何数组类型的缺失值;仅限于 'object' 类型数组(即由 Python 对象构成的数组)

在 Python 中没有定义整数与 None 之间的加法运算。

NaN(Not a Number):一种数值类型的数据缺失标记。它是一种按照IEEE 754浮点数标准设计的一种特殊浮点数,在全球计算机系统中均兼容。 vals2 = np.array([1, np.nan, 3, 4])(vals2.dtype) dtype('float64')请注意,在这种情况下NumPy会为该数组选择其固有的浮点数据类型(与之前基于对象类型的数组不同)。这样的选择使得该数组能够被编译成C代码从而实现高效的运算操作。与之接触过的数据会被感染成为NaN——无论进行何种运算操作,运算结果都会返回NaN值。

尽管 NaN 和 None 各司其职,在实际应用中各有用武之地。然而,在Pandas eyes中它们是可以相互替代的。值得注意的是,在处理数据时可能会遇到这样的情况:Pandas会自动将无标签值的数据类型转为NA标记,并且在适当的时候会将两者进行替换。具体来说,在处理数据时可能会遇到这样的情况:当处理整型数组时,默认情况下缺失值会被转为浮点型NaN;同时也会强制将None替换为NaN以统一数据表示方式。

在这里插入图片描述

处理缺失值

Pandas主要认为None和NaN被视为可相互替代的缺失值形式。为了实现这一替代过程,Pandas提供了若干方法用于识别、去除以及取代数据结构中的缺失值,主要包括以下几种情况

isnull()
创建了一个布尔类型的掩码标签来标记标签中的缺失值。
notnull()
的操作与
isnull()
相反。
dropna()
返回了一个剔除所有缺失值的数据集。
fillna()
返回了一个填充所有缺失值后的数据副本。

识别数据中的缺失值情况
在Pandas库中存在两种强大的工具用于检测数据中的缺失值:isnull()notnull()方法。这两种方法都会生成布尔类型的掩膜数组;

除了前面介绍的掩码方法外,还提供了两个非常实用的处理方法:删除缺失数据(dropna)和填充缺失值(fillna)。其中,默认情况下,默认参数设置为 how=‘any’(如果有任何一个单元格存在缺失值,则会删除该整行或整列),你可以通过 axis 参数指定操作的坐标轴方向。此外还可以设置 how=‘all’(只会删除所有单元格均为缺失值的行或列),并可通过 thresh 参数指定行或列中至少需要有多少个非缺失值才能进行删除操作。

  1. 填充缺失值
    有时候你可能不想删除缺失值而将其替换成有效的数值。这些有效数值可能是像0、1、2这样的单一数值也可能是经过插补或转换得到的结果。虽然你可以通过isnull()方法来创建一个掩码用于填充缺失值但Pandas为此专门提供了fillna()方法它会返回一个新数组副本并将这些位置替换为指定的数值。

将用一个单独的值来填充缺失值,例如用 0:
data.fillna(0)

我们可以利用前一个有效观测值来通过向前填充法进行数据填补(forward-fill):data.fillna(method=‘ffill’)`

也可以用缺失值其后的有效数据点进行回填(backfilling from behind):回填方向

层级索引

Pandas 提供了 Panel 和 Panel4D 对象来处理三维数据与四维数据的问题。 实践中更直观的方式是利用层级索引配合多级索引来组织高维数据集,并将其转换为类似一维 Series 或二维 DataFrame 的形式以方便分析和操作。

多级索引Series

Pandas支持多级索引系统

index = pd.MultiIndex.from_tuples(index)
index

该结构通过指定两个层级数组来定义——levels参数包含各州及特定年份的数据;你可以理解为该结构通过levels属性设置了多级索引层次;这样做的意义在于能够将各个州以及不同年份分别标记为数据中的独立标签。

高维数据的多级索引

该函数能够高效地将一个多级索引的数据框转换为带有普通索引的DataFrame。

当然了,也有 stack() 方法实现相反的效果:
pop_df.stack()

如果我们使用基于多层次键的一维Series结构来表示二维表格结构的话,并非问题所在;那么就可以将这种一维Series扩展至任意数量维度的表层结构;每添加一个层次的索引级别即可增加一个新的数据维度;这样一来就无需担心复杂性问题;从而能够轻松构建具有任意数量维度的数据模型。

多级索引的创建方法

为 Series 或 DataFrame 构建多级索引的最简单方式是将 index 参数配置为一个二维以上的索引数组。通过指定 levels(由每个层级的索引值列表构成)和 labels(由每个值对应的标签列表构成),可以轻松构建 MultiIndex结构:
pd.MultiIndex(levels=[[‘a’, ‘b’], [1, 2]],labels=[[0, 0, 1, 1], [0, 1, 0, 1]])

该 MultiIndex 等级命名会对某些操作带来便利。
为某些操作带来便利的情况下,
为某些操作带来便利的情况下,
在创建任何 MultiIndex 构造器时,
可以在其构造过程中指定参数 names 来命名各个等级,
或者在构造完成后通过索引对象的 names 属性进行调整:
例如:
pop.index.names = [‘state’, ‘year’]
注:上述代码用于为索引对象指定层次名称。

所有 DataFrame 中的行与列都呈现对称结构。因此如果某个 DataFrame 具备多级行索引,则同样可以具备多级列索引。

多级行列索引
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=[‘year’, ‘visit’])

The columns variable is assigned to a MultiIndex created using the product of two lists: one containing ['Bob', 'Guido', 'Sue'] and another with ['HR', 'Temp']. This MultiIndex is further configured with names specified as ['subject', 'type'].

多级索引的取值与切片

多级索引行列转换

有序索引与无序索引 若一个 MultiIndex 不是一个有序的索引 那么会导致大部分切片操作无法成功执行 此外 它还提供了多种简便的方法来处理排序问题 包括 sort_index() 和 sortlevel() 函数 如果 MultiIndex 是一个无序的多级层次索引 那么会导致大部分层级切片操作也无法成功执行 同时 多层嵌套结构进一步增加了切片操作的复杂性

2.索引stack与unstack

该多级索引数据集可通过设置指定层级参数将其转换为二维形式;通过指定 level 参数可调整转换后的索引层级;运行 pop.unstack(level=0) 将执行相应的操作。

unstack() 是 stack() 的逆运算,并且通过这种方法使得数据维持现状: pop.unstack().stack()

  1. 索引的设置与重置 另一种层次数据维度转换的方法是行列标签转换, 可以通过 reset_index 方法来完成

多级索引的数据累计方法

Pandas内置了多种数据累积方法,在数据分析中非常实用。这些方法包括mean、sum和max函数等基本统计运算。对于具有层级索引的数据结构,则可以通过设置参数level来实现对特定子集的累积计算功能。

为了计算每个年度各项指标的平均值,则可将参数 level 设定为年度索引:
data_mean = health_data.mean(level="year")

为了计算每个年度各项指标的平均值,则可将参数 level 设定为年度索引:
data_mean = health_data.mean(level="year")

合并数据集:Concat与Append操作

在数据科学领域中,将不同来源的数据进行整合是一项极具吸引力的任务。这不仅限于简单地将两个不同的数据集直接拼接,同样可以利用类似于数据库中的连接(join)和合并(merge)操作来处理具有共同字段的数据集。Series和DataFrame都支持类似的集成操作,通过Pandas的丰富函数库和集成方法实现高效的并行处理更为便捷。

知识回顾:NumPy数组的合并

合并Series 与 DataFrame 与合并NumPy 数 组 基 本 相 同, 后 者 np.concatenate 函数即可完成。你可以用这个函数将两个或两个以上的数组合并成一个数组。
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
np.concatenate([x, y, z])
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

在进行数组拼接操作时,请注意第一个参数用于指定所有参与合并的数组列表或元组。其中变量x被定义为一个包含两个子数组的一维列表。此外,在设置合并的方向时,请注意使用axis参数。在调用numpy中的concatenate函数时,默认情况下会沿第一个轴进行拼接。这样就得到了一个新的二维数组,在每一列上依次重复了原始数据一次。

通过pd.concat实现简易合并

Python库Pandas提供了一个名为pd.concat()的函数,在功能上与NumPy库中的concatenate函数具有相似性。但其配置参数数量显著增加的同时其功能也更加丰富:

\texttt{pd}\texttt{.concat}(\texttt{objs}, \texttt{axis}=0,\texttt{join='outer'},\texttt{join\_axes=None},\texttt{ignore\_index=False},\texttt{keys=None},\texttt{levels=None},\texttt{names=None},\texttt{verify\_integrity=False},\texttt{copy=True})

全部评论 (0)

还没有任何评论哟~