数据结构:Series 对象

已完成

SeriesDataFrames 与你在 NumPy 模块中遇到的 ndarrays 非常相似。 它们以数据科学所需的规模提供简洁、高效的数据存储和处理。 但是,这两种方法都能提供 ndarrays 所缺乏的重要数据科学功能,例如在处理缺失数据时的灵活性和标记数据的功能。 这些功能(及其他功能)使得 SeriesDataFrames 对于在数据科学中占据重要部分的“数据整理”来说至关重要。

Pandas 中的 Series 对象

Pandas Series 与 NumPy 中的 ndarray 非常相似,它是索引数据的一维数组。 可根据数据数组创建简单的 Series,如下所示:

Series_example = pd.`Series`([-0.5, 0.75, 1.0, -2])
Series_example

输出为:

0   -0.50
1    0.75
2    1.00
3   -2.00
dtype: float64

ndarray 类似,Series 向上转换条目,使其与数据类型相同(原始数组中的整数 -2 在 Series 中为浮点数 -2.00)。

ndarray 的不同之处是,Series 会自动包装值序列和索引序列。 它们是 Series 对象中两个单独的对象,你可使用 valuesindex 特性来访问它们。

首先请尝试访问 values。 它们只是一个常见的 NumPy 数组:

Series_example.values

输出为:

array([-0.5 ,  0.75,  1.  , -2.  ])

index 也是一个类似数组的对象:

Series_example.index

输出为:

RangeIndex(start=0, stop=4, step=1)

ndarrays 一样,可通过常见的 Python 方括号 Series 索引表示法和切片来访问 [] 中的特定数据元素:

series_example[1]

输出为:

0.75

另一个示例:

series_example[1:3]

输出为:

1    0.75
2    1.00
dtype: float64

尽管有很多相似之处,但 Pandas Series 与 NumPy ndarrays 之间有重大区别。 ndarrays 有隐式定义的整数索引(和 Python 列表一样),Pandas 有显式定义的索引Series。 最棒的部分是你可设置索引:

Series_example2 = pd.`Series`([-0.5, 0.75, 1.0, -2], index=['a', 'b', 'c', 'd'])
Series_example2

输出为:

a   -0.50
b    0.75
c    1.00
d   -2.00
dtype: float64

这些显式索引的工作方式完全符合你的预期:

Series_example2['b']

输出为:

0.75

亲自试一试

你现在已在 Jupyter Notebook 中体验并试用了 Python,接下来请使用这些新增的强大能力进行预测和测试。

  • 预测:如果使用显式索引对 series_example2 进行切片,会发生什么情况?
  • 测试:在 Visual Studio Code 中试用。 输出的结果和你的预测的一样吗?

提示(展开以显示)
series_example2['b':]
b    0.75
c    1.00
d   -2.00
dtype: float64




Series 显式索引的工作方式是否与你预期的完全相同? 请尝试使用显式索引对 Series_example2 进行切片并查看结果。

混搭使用显式索引时,Series 基本上是一个固定长度的有序字典,因为它会将任意类型化的索引值映射到任意类型化的数据值。 但与 ndarrays 一样,这些数据的类型都相同,这一点非常重要。 对于某些操作而言,ndarray 后面类型特定的编译代码使得它们比 Python 列表更高效,同样对于某些操作,Pandas Series 的类型信息使它们比 Python 字典更有效。

Series 和字典之间的连接却非常真实。 可直接从 Python 字典构造 Series 对象:

population_dict = { 'France': 65429495,
                    'Germany': 82408706,
                    'Russia': 143910127,
                    'Japan': 126922333 }
population = pd.`Series`(population_dict)
population

输出为:

France      65429495
Germany     82408706
Russia     143910127
Japan      126922333
dtype: int64

你看到发生了什么情况吗? 对于“俄罗斯”和“日本”键,它们在 中输入的顺序与它们在 population_dict 中结尾的顺序之间换了位置populationSeries。 虽然 Python 字典键没有顺序,但会对 Series 键进行排序。

因此在一个级别上,你可以像与字典交互那样与 Series 进行交互:

population['Russia']

输出为:

143910127

亲自试一试

但你也可使用 Series 执行类似数组的强大操作,例如切片。

  • 预测:如果 Series 键未排序,那么能否进行切片?
  • 测试:在 Visual Studio Code 中试用。 创建未排序的 Series,并尝试将其切片。 它是否实现了你所期望的?

提示(展开以显示)
population['Germany':]
Germany     82408706
Japan      126922333
Russia     143910127
dtype: int64




亲自试一试

你还可向 Series 添加元素,就像向 ndarray 添加元素一样。

  • 尝试将元素添加到下面代码单元中的 Series
  • 尝试运行 population['Albania'] = 2937590(或所选的其他国家/地区)。
  • 预测运行 population 时键出现的顺序。 是否与你的预期相同?

提示(展开以显示)
population['Albania'] = 2937590
population
France      65429495
Germany     82408706
Japan      126922333
Russia     143910127
Albania      2937590
dtype: int64




还有一种有用的 Series 功能(与字典绝对不同)是,Series 会在算术运算中自动对齐不同索引的数据:

pop2 = pd.`Series`({'Spain': 46432074, 'France': 102321, 'Albania': 50532})
population + pop2

输出为:

Albania           NaN
France     65531816.0
Germany           NaN
Japan             NaN
Russia            NaN
Spain             NaN
dtype: float64

请注意,在德国、日本、俄罗斯和西班牙(根据你在前述练习中执行的操作,可能还包括阿尔巴尼亚),加法运算会生成 NaN(不是数字)值。 Pandas 不会将缺失值视为 0,而是将它视为 NaN。 (将涉及 NaN 的算术运算视为实质上是 $NaN + x = NaN$ 会很有帮助)。