首页 > pandas 阅读数:52

pandas Series对象创建及常用操作

pandas 的核心是 Series 和 DataFrame 两大数据结构,数据分析相关的所有事务都是围绕着这两种结构进行的。其中,Series 数据结构用于存储一个序列的一维数组,而 DataFrame 数据结构则用于存储复杂数据的二维数据结构。

虽然这些数据结构不能解决所有的问题,但它们为大多数应用提供了有效且强大的工具,就简洁性而言,理解和使用它们都很简单。此外,很多更为复杂的数据结构都可以追溯到这两种结构。本节教程就对这两种结构中的 Series 重点介绍。

Series 是一种类似于一维数组的对象,它是由一组数据(可以是 NumPy 中任意类型的数据)以及一组与之相关的数据标签组成的。Series 对象的内部结构是由两个相互关联的数组组成的,其中用于存放数据(即值)的是 value 主数组,主数组的每个元素都有一个与之相关联的标签(即索引),这些标签存储在另外一个叫作 Index 的数组中。

Series 的表现形式为:索引在左边,值在右边。例如,Series 对象 [2,4,-3,7] 的内部结构如图 1 所示。

Series内部结构
图 1:Series 内部结构

1. 创建 Series 对象

1) 通过 Series() 构造函数创建

创建 Series 对象的 Series() 构造函数如下:

pandas.Series(data[, index])

函数中的参数说明如下:
  • data 是输入给 Series 构造器的数据,它可以是 NumPy 中任意类型的数据;
  • index 是 Series 对象中数据的标签(即索引)。

创建过程:调用 Series() 构造函数,把要存放在 Series 对象中的数据以数组形式传入,就能创建一个 Series 对象。例如,在 Jupyter Notebook 下输入下列代码:
In [1]:  import pandas as pd
In [2]:  se1 = pd.Series([2,4,-3,7])
此代码声明了一个 Series 对象 se1,输出 se1,可见左边是标签,右边是标签对应的元素。

In [3]:  se1
Out[3]:  0   2
         1   4
         2  -3
         3   7
         dtype:int64
声明 Series 时,若不指定标签,pandas 默认使用从 0 开始依次递增的数值作为标签,此时,标签与 Series 对象中元素的索引(在数组中的位置)是一致的。

但是,如果想对各个数据使用有特定意义的标记(标签),就必须在调用 Series()构 造函数时,指定 index 选项,把存放有标签的数组赋值给 index。例如,设置标签的 Series 声明如下:
In [4]:  se2 = pd.Series([2,4,-3,7],index=['b','c','a','d'])
In [5]:  se2
Out[5]:  b    2
         c    4
         a   -3
         d    7
         dtype: int64

2) 用 NumPy 数组或其他 Series 对象定义新的 Series 对象

① 用 NumPy 数组定义新的 Series 对象代码如下:
In [6]:  import numpy as np
In [7]:  arr = np.array([2,3,4,5])
In [8]:  se3 = pd.Series(arr)
In [9]:  se3
Out[9]:  0    2
         1    3
         2    4
         3    5
         dtype: int32

② 用其他 Series 对象定义新的 Series 对象命令如下:
In [10]:  se4 = pd.Series(se2)
In [11]:  se4
Out[11]:  b    2
          c    4
          a   -3
          d    7
          dtype: int64

注意:利用这两种方法创建的新 Series 对象中的元素不是原 NumPy 数组或 Series 对象元素的副本,而是对它们的引用。也就是说,这些对象是动态插入到新 Series 对象中的。如改变原有对象元素的值,新 Series 对象中这些元素也会发生变化。

3) 将字典转换为 Series 对象

如果数据存放在字典中,字典中的一个键与值的映射关系,可以被看成是 Series 对象中的索引值到数据值的一个映射,因此,可以将字典直接转换为 Series 对象。
In [12]:  s_data = {'s_number':20171010, 'Normal':86, 'exam':90}
In [13]:  se5 = pd.Series(s_data)
In [14]:  se5
Out[14]:  s_number    20171010
          Normal            86
          exam              90
          dtype: int64

注意:将字典直接转换为 Series 对象,当字典中值发生变化时,转换为 Series 对象中的元素不会变化。同样,也可以将 Series 对象转换成字典。

2. 查看 Series 值和标签

通过 Series 的属性 values 和 index 可查看值和标签。

例如:se2.values 查看值和 se2.index 查看标签。

3. 选择内部元素

Series 索引的工作方式类似于 NumPy 数组的索引,只不过 Series 的索引值不只是整数。

1) 选择单个元素

若想获取 Series 对象的内部元素,把它看成普通的 NumPy 数组,指定索引即可。例如,se1[2] 获取元素是 -3。

或者指定位于索引位置处的标签。例如,se2['a'] 获取的元素也是 -3。

2) 选择多个元素

通过 Series 索引的切片来选择多个元素时,切片“[起始值:终止值:步长]”所指定的元素是不包含终止值的元素,如没有指定终止值,则终止值是包含 Series 最后索引的元素。
In [15]:  se1[0:2]
Out[15]:  0     2
          1     4
          dtype: int64

或者可以使用元素对应的标签,只不过要把标签放在数组中。
In [16]:  se2[['a','d']]
Out[16]:  a    -3
          d     7
          dtype: int64

如利用标签的切片来选择多个元素时,切片“[起始标签:终止标签]”所指定的元素是包含终止标签的元素,如果没有指定终止标签,则终止标签是包含 Series 最后标签的元素。
In [17]:  se6 = pd.Series([1,2,3,4],index=['a', 'b', 'c', 'd'])
In [18]:  se6['b':'c']
Out[18]:  b    2
          C    3
          dtype: int64

4. 给元素赋值

通过索引或标签选取元素后直接进行赋值。例如,se1[1]=1 或 se2['a']=0。

5. Series 对象的简单运算

pandas 库开发是以 NumPy 库为基础的,从数据结构而言,NumPy 数组中的许多操作都会保留到 Series 对象中,如根据条件筛选数据。还有适用于 NumPy 数组的算术运算符( +、-、*、/ )和其他数学函数等,也适用于 Series 对象。

1) 筛选元素

筛选元素就是根据条件筛选数据结构中的元素。例如,筛选 se1 中大于 3 的元素。
In [19]:  se1[se1>3]
Out[19]:  1     4
          3     7
          dtype: int64

2) 算术运算和数学函数

例如:se1*2、np.exp(se1)。

6. Series 对象之间的运算

在 Series 对象之间进行运算时,Series 能够通过识别标签对齐不一致的数据。这就是 Series 运算时的自动对齐功能。例如,将 se1 与 se1[se1>3] 相加,其结果如下:
In [20]:  se1 += se1[se1>3]
In [21]:  se1
Out[21]:  0     NaN
          1     8.0
          2     NaN
          3     14.0
          dtype: float64
通过上述计算得到了一个新 Series 对象,其中只对标签相同的元素求和,其他只属于各自的 Series 对象的标签也被添加到新对象中,只不过它们的值为 NaN。

7. NaN

一般来讲,NaN 表示数据有问题,必须对其进行处理,尤其是在数据分析时。从某些数据源抽取数据时遇到了问题,甚至是数据源缺失数据时,往往会产生这类数据。另外,在执行计算和函数运算时也会遇到这类数据。有关 NaN 数据的处理方法以后我们将进行介绍。

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

8. 统计 Series 对象的组成元素

Series 对象往往包含重复元素,因此,统计元素重复出现的次数和判断元素是否存在 Series 对象中是常用的操作。

1)  统计元素重复出现的次数

统计 Series 对象包含多少个不同的元素,可使用 unique() 函数返回一个由 Series 去重后的元素所组成的数组,但是数组中元素的顺序不会自动排序。
In [22]:  se = pd.Series([5,1,4,1,2,2])
In [23]:  se.unique()
Out[23]:  array([5, 1, 4, 2], dtype=int64)

另外,还有一个 value_counts() 函数,它不仅能返回各个不同的元素,而且还能计算每个元素在 Series 中的出现次数。运行结果中左边是元素,右边是元素出现的次数。
In [24]:  se.value_counts()
Out[24]:  2     2
          1     2
          5     1
          4     1
          dtype: int64

2) 判断元素是否存在

使用 isin() 函数可以判断给定的一列元素是否包含在 Series 数据结构中,如果给定的元素包含在数据结构中,isin() 函数返回是 True,否则返回是 False。利用此函数可以筛选 Series 或 DataFrame 列中的数据。
In [25]:  se.isin([0,2])
Out[25]:  0     False
          1     False
          2     False
          3     False
          4     True
          5     True
          dtype: bool