9.6 聚合: 最小, 最大和之间的任何东西
本节是《Python 数据科学手册》(Python Data Science Handbook) 的摘录.
译者: 飞龙 https://github.com/wizardforcel
协议: CC BY-NC-SA 4.0 http://creativecommons.org/licenses/by-nc-sa/4.0/
通常, 当面对大量数据时, 第一步是计算相关数据的汇总统计信息.
也许最常见的汇总统计数据是均值和标准差, 它允许你汇总数据集中的 "典型" 值, 但其他汇总也很有用 (总和, 乘积, 中位数, 最小值和最大值, 分位数等).
NumPy 具有内置的快速的聚合函数, 可用于处理数组; 我们将在这里讨论和演示其中的一些内容.
对数组中的值求和
作为一个简单的例子, 考虑计算数组中所有值的总和. Python 本身可以使用内置的 sum 函数来实现:
- import numpy as np
- L = np.random.random(100)
- sum(L)
- # 55.61209116604941
NumPy 的 sum 函数的语法非常相似, 结果在最简单的情况下是相同的:
- np.sum(L)
- # 55.612091166049424
但是, 因为它在编译代码中执行操作, 所以操作的 NumPy 版本计算速度更快:
- big_array = np.random.rand(1000000)
- %timeit sum(big_array)
- %timeit np.sum(big_array)
- '''
- 10 loops, best of 3: 104 ms per loop
- 1000 loops, best of 3: 442 μs per loop
- '''
但要小心: sum 函数和 np.sum 函数不相同, 有时会产生混乱!
特别是, 它们的可选参数具有不同的含义, 并且 np.sum 知道多个数组维度, 我们将在下一节中看到.
最小和最大
类似地, Python 内置了 min 和 max 函数, 用于查找任何给定数组的最小值和最大值:
- min(big_array), max(big_array)
- # (1.1717128136634614e-06, 0.9999976784968716)
NumPy 的相应函数具有相似的语法, 并且同样运行得更快:
- np.min(big_array), np.max(big_array)
- # (1.1717128136634614e-06, 0.9999976784968716)
- %timeit min(big_array)
- %timeit np.min(big_array)
- '''
- 10 loops, best of 3: 82.3 ms per loop
- 1000 loops, best of 3: 497 μs per loop
- '''
对于 min,max,sum 和其他几个 NumPy 聚合, 更短的语法是使用数组对象本身的方法:
- print(big_array.min(), big_array.max(), big_array.sum())
- # 1.17171281366e-06 0.999997678497 499911.628197
只要有可能, 请确保在 NumPy 数组上运行时, 使用这些聚合的 NumPy 版本!
多维聚合
一种常见类型的聚合操作是沿行或列的聚合. 假设你有一些存储在二维数组中的数据:
- M = np.random.random((3, 4))
- print(M)
- '''
- [[ 0.8967576 0.03783739 0.75952519 0.06682827]
- [ 0.8354065 0.99196818 0.19544769 0.43447084]
- [ 0.66859307 0.15038721 0.37911423 0.6687194 ]]
- '''
默认情况下, 每个 NumPy 聚合函数都将返回整个数组的聚合:
- M.sum()
- # 6.0850555667307118
聚合函数接受另一个参数来指定计算聚合的轴. 例如, 我们可以通过指定 axis = 0, 寻找每列中的最小值:
- M.min(axis=0)
- # array([ 0.66859307, 0.03783739, 0.19544769, 0.06682827])
该函数返回四个值, 对应于四列数字. 同样, 我们可以在每行中找到最大值:
- M.max(axis=1)
- # array([ 0.8967576 , 0.99196818, 0.6687194 ])
此处指定轴的方式, 可能会使来自其他语言的用户感到困惑. axis 关键字指定要折叠的数组的维度, 而不是将返回的维度.
因此, 指定 axis = 0 意味着折叠第一个轴: 对于二维数组, 这意味着将聚合每列中的值.
其它聚合函数
NumPy 提供了许多其他聚合函数, 但我们不会在这里详细讨论它们.
此外, 大多数聚合都有一个 NaN 安全的替代品来计算结果, 同时忽略缺失值, 缺失值由特殊的 IEEE 浮点 NaN 值标记 (对于缺失数据的更全面讨论, 请参阅 " 处理缺失数据).
其中一些 NaN 安全的函数直到 NumPy 1.8 才被添加, 所以它们在旧的 NumPy 版本中不可用.
下表提供了 NumPy 中可用的实用聚合函数的列表:
函数名称 | NaN 安全的版本 | 描述 |
---|---|---|
np.sum | np.nansum | 计算元素的和 |
np.prod | np.nanprod | 计算元素的积 |
np.mean | np.nanmean | 计算元素的均值 |
np.std | np.nanstd | 计算标准差 |
np.var | np.nanvar | 计算方差 |
np.min | np.nanmin | 寻找最小值 |
np.max | np.nanmax | 寻找最大值 |
np.argmin | np.nanargmin | 寻找最小值的下标 |
np.argmax | np.nanargmax | 寻找最大值的下标 |
np.median | np.nanmedian | 计算元素的中值 |
np.percentile | np.nanpercentile | 计算元素的百分位数 |
np.any | N/A | 计算是否任何元素是真 |
np.all | N/A | 计算是否所有元素是真 |
我们将在本书的其余部分经常看到这些聚合.
示例: 美国总统的平均身高是多少?
NumPy 中可用的聚合对于汇总一组值非常有用. 举个简单的例子, 让我们考虑所有美国总统的身高. 此数据位于 president_heights.CSV 文件中, 该文件是一个简单的逗号分隔的标签和值的列表:
- !head -4 data/president_heights.CSV
- '''
- order,name,height(cm)
- 1,George Washington,189
- 2,John Adams,170
- 3,Thomas Jefferson,189
- '''
我们将使用 Pandas 软件包, 来读取文件并提取信息 (请注意, 高度以厘米为单位). 我们将在第三章中更全面地探索 Pandas.
- import pandas as pd
- data = pd.read_csv('data/president_heights.csv')
- heights = np.array(data['height(cm)'])
- print(heights)
- '''
- [189 170 189 163 183 171 185 168 173 183 173 173 175 178 183 193 178 173
- 174 183 183 168 170 178 182 180 183 178 182 188 175 179 183 193 182 183
- 177 185 188 188 182 185]
- '''
现在我们有了这个数据数组, 我们可以计算各种汇总统计数据:
- print("Mean height:", heights.mean())
- print("Standard deviation:", heights.std())
- print("Minimum height:", heights.min())
- print("Maximum height:", heights.max())
- '''
- Mean height: 179.738095238
- Standard deviation: 6.93184344275
- Minimum height: 163
- Maximum height: 193
- '''
请注意, 在每种情况下, 聚合操作都会将整个数组缩减为单个汇总值, 从而为我们提供值分布的信息.
我们也可能打算计算分位数:
- print("25th percentile:", np.percentile(heights, 25))
- print("Median:", np.median(heights))
- print("75th percentile:", np.percentile(heights, 75))
- '''
- 25th percentile: 174.25
- Median: 182.0
- 75th percentile: 183.0
- '''
我们看到美国总统的身高中值为 182 厘米, 或者只有 6 英尺.
当然, 有时看到这些数据的直观表示更有用, 我们可以使用 Matplotlib 中的工具来完成 (我们将在第四章中更全面地讨论 Matplotlib). 例如, 此代码生成以下图表:
- %matplotlib inline
- import matplotlib.pyplot as plt
- import seaborn; seaborn.set() # 设置绘图风格
- plt.hist(heights)
- plt.title('Height Distribution of US Presidents')
- plt.xlabel('height (cm)')
- plt.ylabel('number');
这些聚合是探索性数据分析的一些基本部分, 我们将在本书的后续章节中进行更深入的探索.
来源: https://juejin.im/entry/5c2f0c2ae51d45520e537aae