这篇文章向你解释了如何使用NumPy中的nonzero() 函数查找数组元素--使用一个实际的数据科学例子。
np.nonzero()的实际应用场景
城市化的大趋势不会很快停顿下来。汽车、工厂和其他污染源最终导致了糟糕的空气质量。这个单行本向你展示了如何从数据科学家的角度来处理它!
这个例子取自我的书Python One-Liners。
空气质量指数 (AQI)衡量不利健康影响的危险性。它通常被用来比较不同城市的空气质量。在这单行线中,你将深入四个城市的空气质量指数。香港、纽约、柏林和蒙特利尔。
单行本解决的问题是寻找高于平均水平的污染城市。我们将它们定义为空气质量指数峰值高于所有城市所有测量值中的总体平均水平的城市。
我们解决方案的一个重要元素将是在NumPy数组中找到满足某个条件的元素。这是数据科学中一个常见的问题,在你的实际代码项目中,你会不断需要它。
因此,让我们探讨一下如何找到满足某个条件的数组元素。
NumPy提供了函数nonzero() ,它可以找到数组中不等于零的元素的索引,嗯,不等于零。下面是一个例子。
import numpy as np
X = np.array([[1, 0, 0],
[0, 2, 2],
[3, 0, 0]])
print(np.nonzero(X))
# (array([0, 1, 1, 2], dtype=int64), array([0, 1, 2, 0], dtype=int64))
的结果是两个NumPy数组的一个元组。第一个数组给出了
非零元素的行索引。第二个数组给出了非零元素的列索引。
在二维数组中,有四个非零元素。1,2,2,和3。这 四个非零元素在数组中的位置(0,0),(1,1),(1,2)和(2,0)。
现在,你如何使用nonzero()来寻找数组中符合某个条件的元素呢?只需使用另一个伟大的NumPy功能。用广播进行布尔数组操作!
import numpy as np
X = np.array([[1, 0, 0],
[0, 2, 2],
[3, 0, 0]])
print(X == 2)
"""
[[False False False]
[False True True]
[False False False]]
"""
这个 ,实际上是一个广播的实例:整数值 "2 "被复制(概念上) 到一个新的具有相同形状的数组。然后NumPy进行了一个元素间的比较 ,并返回结果的布尔数组。 你对如何结合nonzero()和布尔数组 ,找到满足某个条件的元素有了想法吗?
提示。Python将 "False "数据类型表示为一个数值为 "0 "的整数。
看一下下面的代码片断,看看如何做到这一点。
在代码片断中,我们探讨了以下问题。 "找到污染峰值高于平均水平的城市!"
## Dependencies
import numpy as np
## Data: air quality index AQI data (row = city)
X = np.array(
[[ 42, 40, 41, 43, 44, 43 ], # Hong Kong
[ 30, 31, 29, 29, 29, 30 ], # New York
[ 8, 13, 31, 11, 11, 9 ], # Berlin
[ 11, 11, 12, 13, 11, 12 ]]) # Montreal
cities = np.array(["Hong Kong", "New York", "Berlin", "Montreal"])
## One-liner
polluted = set(cities[np.nonzero(X > np.average(X))[0]])
## Result
print(polluted)
数据数组X包含四行(每个城市有一个行)和六列(每个测量单位有一列--例如:
天)。字符串数组cities包含四个城市的名称,按照它们在数据数组中出现的顺序 。
问题是要找到那些观察到的AQI值高于平均水平的城市名称。同样,这里是完成这一任务的单行代码。
## One-liner
polluted = set(cities[np.nonzero(X > np.average(X))[0]])
让我们从内部开始解构这个单行代码。
print(X > np.average(X))
"""
[[ True True True True True True]
[ True True True True True True]
[False False True False False False]
[False False False False False False]]
"""
布尔表达式使用广播来使两个操作数达到相同的形状。然后进行元素比较,得出一个布尔数组,如果相应的测量值观察到高于平均的AQI值,则该数组包含 "真"。我们使用函数np.average()来计算所有NumPy数组元素的平均AQI值。
通过生成这个布尔数组,我们知道 ,到底哪些元素满足高于平均水平的条件,哪些元素不满足。
回顾一下,Python的 "真 "值用 "1 "表示,"假 "用 "0 "表示。因此,我们可以使用函数nonzeros()来找到所有满足条件的行和列索引。下面是如何做到这一点的。
print(np.nonzero(X > np.average(X)))
"""
(array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2], dtype=int64),
array([0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 2], dtype=int64))
"""
第一个元组值持有所有具有非零元素的行索引,第二个元组值持有它们各自的列索引。换句话说,这些是数据矩阵中AQI值超过平均污染的所有行和列。
我们只对行指数感兴趣,因为我们正在寻找数据中发生这种污染窥探的城市。我们可以使用这些行指数从我们的字符串数组中提取字符串名称。
print(cities[np.nonzero(X > np.average(X))[0]])
"""
['Hong Kong' 'Hong Kong' 'Hong Kong' 'Hong Kong' 'Hong Kong' 'Hong Kong' 'New York' 'New York' 'New York' 'New York' 'New York' 'New York' 'Berlin']
"""
在结果的字符串序列中,有很多重复的。原因是香港和纽约有很多,这种高于平均水平的AQI测量。
现在,只剩下一件事了:去除重复的内容。这可以通过将序列转换为Python集合来轻松实现。集合是无重复的,所以结果给了我们所有污染超过平均AQI值的城市名称。