zhengzhuaguazi

人工智能之Python数据挖掘—— pandas 库

一. pandas:Python 数据分析库

  pandas 是一个专门用于数据分析的开源 Python 库。使用 Python 语言研究和分析数据集,做相关统计分析和决策时,pandas 都是基础工具。

  数据分析工作需要一个专门的库,,它能够以最简单的方式提供数据处理。数据抽取和数据操作所需的全部工具。开发 pandas 正是为了满足这个需求。

  以 NumPy 库作为 Python 库 pandas 的基础进行设计,不仅使 pandas 能和其他大多数模块相兼容,而且还能借力 NumPy 模块在计算方面性能高的优势。此外,pandas 没有使用 Python 已有的内置数据结构,也没有使用其他库的数据结构,而是开发了两种新型的数据结构,用它们去更方便地管理与 SQL 关系数据库和 Excel 工作表具有类似特征的数据。

1. pandas 数据结构简介

  pandas 的核心为两个数据结构,数据分析相关的所有事务都是围绕着这两种结构进行的:

  • Series
  • DataFrame

  Series 这类数据结构用于存储一个序列这样的一维数据,而 DataFrame 作为更复杂的数据结构,则用于存储多维数据。

1.1 Series 对象

  pandas 库的 Series 对象用来表示一维数据结构,跟数组类似,但多了一些额外的功能。它的内部结构由两个相互关联的数组组成,其中主数组用来存放数据(NumPy 任意类型数据)。主数组的每个元素都有一个与之相关联的标签,这些标签存储在另外一个叫做 Index 的数组中。

Series
index value
0 12
1 -4
2 7
3 9

1.1.1 声明 Series 对象

  调用 Series()构造函数,把要存放在 Series 对象中的数据以数组形式传入,就能创建一个如上图所示的 Series 对象。

>>> s=pd.Series([12,-4,7,9])
>>> s
0    12
1    -4
2    7
3    9
dtype: int64

  从 Series 的输出可以看到,左侧 Index 是一列标签,右侧是标签对应的元素。

  声明 Series 时,若不指定标签,pandas 默认使用从 0 开始依次递增的数值作为标签。这种情况下,标签与 Series 对象中元素的索引(在数组中的位置)一致。

  然而,最好使用有意义的标签,用以区分和识别每个元素,而不用考虑元素插入到 Series 中的顺序。

  因此,调用构造函数时,就需要指定 index 选项把存放有标签的数组赋给它,其中标签为字符串类型

>>> s=pd.Series([12,-4,7,9]),index=[\'a\',\'b\',\'c\',\'d\']
>>> s
a    12
b    -4
c    7
d    9
dtype:int64

  如果想分别查看组成 Series 对象的两个数组,可以像下面这样调用它的两个属性:index(索引)和 values(元素)。

>>> s.values
array([12,-4,7,9],dtype=64)
>>> s.index
Index([u\'a\',u\'b\',u\'c\',u\'d\'],dtype=\'object\') 不懂

1.1.2 选择内部元素

  若想获取 Series 对象内部的元素,把它作为普通的 NumPy 数组,指定键即可。

  >>> s[2]

  7

  或者,指定位于索引位置处的标签。

  >>> s[\'b\']

  -4

  跟从 NumPy 数组选择多个元素的方法相同,可像下面这样选取多项:

  >>> s[0:2]

  a      12

  b       -4

  dtype:int64

  或者, 这种情况甚至可以使用元素对应的标签,只不过要把标签放到数组中:

  >>> s[\'b\',\'c\']

  b       -4

  c      7

  dtype:int64

1.1.3 为元素赋值

  赋值方法可以用索引或标签选取元素后进行赋值。

>>> s[1]=0
>>> s
a   12
b    0
c    7
d    9
dtype: int64
>>> s[\'b\']=1
>>> s
a   12
b    1
c    7
d    9
dtype: int64

1.1.4 用 NumPy 数组或其他 Series 对象定义新 Series 对象

>>> arr=np.array([1,2,3,4])
>>> s3=pd.Series(arr)
>>> s3
0    1
1    2
2    3
3    4
dtype: int32
>>> s4=pd.Series(s)
>>> s4
a    12
b     1         # 教材上是 4   ???
c     7
d     9
dtype: int64

  然而,新 Series 对象中的元素不是原 Numpy 数组或 Series 对象元素的副本,而对它们的引用。也就是说,这些对象是动态插入到新 Series 对象中,如果改变原有对象元素的值,新 Series 对象中这些元素也会相应发生变化。 

>>> s3
0     1
1     2
2     3
3     4
dtype: int32
>>> arr[2]=-2
>>> s3
0     1
1     2
2     -2
3     4
dtype: int32

  上述例子,改动 arr 数组第三个元素的值,同时也会修改 Series 对象 s3 中相应的元素。

1.1.5 筛选元素

  pandas 库的开发是以 NumPy 库为基础的,因此就数据结构而言,NumPy 数组的多种操作方法得以扩展到 Series 对象中,其中就有根据条件筛选数据结构中的元素这一方法。

  例如要获取 Series 对象中所有大于8的元素,可使用以下代码:

>>> s[s>8]
a     12
d      9
dtype: int64

1.1.6 Series 对象运算和数学函数

  适用于 NumPy 数组的运算(+、-、*、/)或其他数学函数,也适用于 Series 对象。

  至于运算符,直接用来编写算术表达式即可

>>> s / 2
a     6.0
b     -2.0   # ????
c     3.5
d     4.5
dtype: float64       

  然而,至于 NumPy 库的数学函数,必须指定它们的出处 np,并把 Series 实例作为参数传入。

>>> np.log(s)
a   2.484907
b        NaN
c   1.945910
d   2.197225
dtype: float 64

1.1.7 Series 对象的组成元素

  Series 对象往往包含重复的元素,如果想知道里面都包含哪些元素,统计元素重复出现的次数或判断一个元素是否在 Series 中。

  首先声明一个包含多个重复元素的 Series 对象。

>>> serd=pd.Series([1,0,2,1,2,3],index=[\'white\',\'white\',\'blue\',\'green\',\'green\',\'yellow\'])
>>> serd
white     1
white     0
blue       2
green     1
green     2
yellow    3
dtype: int64

  要想知道 Series 对象包含多少个不同的元素,可使用 unique()函数。其返回结果为一个数组,包含 Series 去重后的元素,但顺序看上去很随意。

>>> serd.nuique()
array([1,0,2,3],dtype=int64)

  跟 unique()函数相似的另外一个函数是 value_counts()函数,它不仅返回各个不同的元素,还计算每个元素在 Series 中的出现次数。

>>> serd.value_counts()
2    2
1    2
3    1
0    1
dtype: int64

  最后,isin()函数用来判断所属关系,也就是判断给定的一列元素是否包含在数据结构之中。isin()函数返回布尔值,可用于筛选 Series 或 DataFrame列中的数据。

>>> serd.isin([0,3])     # 选取serd中值为0或3的行
white False
white True
blue False
green False
green False
yellow True
dtype: bool
>>> serd[serd.isin([0,3])]
white 0
yellow 3
dtype: int64

1.1.8 NaN

  在前面的一个例子中,求负数的对数,得到的返回结果为 NaN(Not a Number,非数值)。数据结构中若字段为空或者不符合数字的定义时,用这个特定的值来表示。

  一般来讲,NaN 值表示数据有问题,必须对其进行处理,尤其是在数据分析时。从某些数据源抽取数据时遇到了问题,甚至是数据源缺失数据,往往就会产生这类数据。进一步来讲,计算负数的对数,执行计算或函数时抛出异常等特定情况,也可能产生这类数据。

  尽管 NaN 值是数据有问题才产生的,然而在 panads 中是可以定义这种类型的数据,并把它添加到 Series 等数据结构中的。创建数据结构时,可为数组中元素缺失的项输入 np.NaN。

>>> s2=pd.Series([5,-3,np.NaN,14])
>>> s2
0      5
1     -3
2    NaN
3     14

  isnull()和notnull()函数用来识别没有对应元素的索引时非常好用。

>>> s2.isull()
0       False
1       False
2       True
3       False
dtype: bool
>>> s2.notnull()
0       True
1       True
2       False
3       True
dtype: bool

  上述两个函数返回两个由布尔值组成的 Series 对象,其元素值是 True 还是 False 取决于原 Series 对象的元素是否为 NaN。如果是 NaN,isnull()函数返回值为 True;反之,如果不是 NaN,notnull()函数返回值为 True。这两个函数可用作筛选条件。

>>> s2[s2.notnull()]
0       5
1       -3
3       14
dtype: float64
>>> s2[s2.isnull()]
2       NaN
dtype: float64

1.1.9 Series 用作字典

  还可以把 Series 对象当做字典对象来用。定义 Series 对象时,就可以利用这种相似性。事实上,可以用事先定义好的字典来创建 Series 对象。

>>> mydict={\'red\':2000,\'blue\':1000,\'yellow\':500,\'orange\':1000}
>>> myseries=pd.Series(mydict)
blue         1000
orange       1000
red          2000
yellow        500
dtype: int64

  上述例子中,索引数组用字典的键来填充,每个索引所对应的元素为用作索引的键在字典中对应的值。可以单独指定索引,pandas 会控制字典的键和数组索引标签之间的相关性。如遇缺失值处,pandas 就会为其添加 NaN。

>>> colors=[\'red\',\'yellow\',\'orange\',\'blue\',\'green\']
>>> myseries=pd.Series(mydict,index=colors)
red         2000
yellow       500
orange      1000
blue        1000
green        NaN
dtype: float64

1.1.10 Series 对象之间的运算

  之前有 Series 对象和标量之间的数学运算,Series 对象之间也可以进行这类运算,甚至标签也可以参与运算。事实上,Series 这种数据结构在运算时有一大优点,它能够通过识别标签对齐不一致的数据。

  在下面的例子中,我们来求只有部分元素标签相同的两个 Series 对象之和。

>>> mydict2={\'red\':400,\'yellow\':1000,\'black\':700}
>>> myseries2=pd.Series(mydict2)
>>> myseries+myseries2
black      NaN
blue       NaN
orange     NaN
green      NaN
red       2400
yellow    1500
dtype: float64

  上述运算得到一个新 Series 对象,其中只对标签相同的元素求和。其他只属于任何一个 Series 对象的标签也被添加到新对象中,只不过它们的值均为 NaN

1.2 DataFrame 对象

  DataFrame 这种列表式数据结构跟工作表(最常见的是 Excel 工作表)极为相似,其设计初衷是将 Series 的使用场景由一维扩展到多维。DataFrame 由一定顺序排列的多列数据组成,各列的数据类型可以有所不同(数值、字符串或布尔值等),如下图所示

DataFrame
  columns
index color object price
0 blue ball 1.2
1 green pen 1.0
2 yellow pencil 0.6
3 red paper 0.9
4 white mug 1.7

   Series 对象的 Index 数组存放有每个元素的标签,而 DataFrame 对象则有所不同,它有两个索引数组。第一个数组与行,它与 Series 的索引数组极为相似。每个标签与标签所在行的所有元素相关联。而第二个数组包含一系列列标签,每个标签与一列数据相关联。

  DataFrame 还可以理解为一个由 Series 组成的字典,其中每一列的名称为字典的键,形成 DataFrame 的列的 Series 作为字典的值。进一步来说,每个 Series 的所有元素映射到叫做 Index 的标签数组。

1.2.1 定义 DataFrame 对象

  新建 DataFrame 对象的最常用方法是传递一个 dict 对象给 DataFrame()构造函数。dict 对象以每一列的名称作为键,每个键都有一个数组作为值。

>>> data={\'color\':[\'blue\',\'green\',\'yellow\',\'red\',\'white\'],
                 \'object\':[\'ball\',\'pen\',\'pencil\',\'paper\',\'mug\'],
                 \'price\':[1.2,1.0,0.6,0.9,1.7]}
>>> frame=pd.DataFrame(data)
>>> frame
      color     object      price
0     blue       ball        1.2
1     green      pen         1.0
2     yellow    pencil       0.6
3      red       paper       0.9
4     white      mug         1.7

  如果用来创建 DataFrame 对象的 dict 对象包含一些用不到的数据,可以只选择自己感兴趣的。在 DataFrame 构造函数中,用 columns 选项指定需要的列即可。新建的 DataFrame 各列顺序与指定的列顺序一致,而与它们在字典中的顺序无关。

>>> frame2

 

分类:

技术点:

相关文章:

  • 2021-07-17
  • 2021-11-07
  • 2021-09-05
  • 2021-11-29
  • 2021-11-04
  • 2021-11-18
  • 2022-12-23
  • 2022-01-22
猜你喜欢
  • 2021-11-28
  • 2021-12-24
  • 2022-02-10
  • 2021-04-10
  • 2022-12-23
  • 2021-12-14
  • 2021-11-21
相关资源
相似解决方案