数据结构:Series 对象
Series 和 DataFrames 与你在 NumPy 模块中遇到的 ndarrays 非常相似。 它们以数据科学所需的规模提供简洁、高效的数据存储和处理。 但是,这两种方法都能提供 ndarrays 所缺乏的重要数据科学功能,例如在处理缺失数据时的灵活性和标记数据的功能。 这些功能(及其他功能)使得 Series 和 DataFrames 对于在数据科学中占据重要部分的“数据整理”来说至关重要。
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 对象中两个单独的对象,你可使用 values 和 index 特性来访问它们。
首先请尝试访问 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$ 会很有帮助)。