上回說到這本書的第二章 Python One-Liners(1)
這回來到第三章,是關(guān)于 Data Science 的一行代碼(這里寫其中一個)
有一個 (4, 6) 的二維數(shù)組 X,每行代表一個城市的空氣質(zhì)量指數(shù) ( AQI )
import numpy as np
## 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(['HongKong','Newyork','Berlin','Montreal'])
問題:找出這幾個城市中空氣質(zhì)量指數(shù)大于平均值的城市。
先給結(jié)果:
## One-Liner
polluted = set(cities[np.nonzero(X > np.average(X))[0]])
# 輸出結(jié)果:
print(polluted)
# {'Berlin', 'HongKong', 'Newyork'}
How It Works?
我們從里到外一步一步拆解
np.average() 用于求 X 的平均值
np.average(X)
## 24.333333333333332
X > np.average(X) 會得到一個布爾值組成的二維數(shù)組遗锣,即橘忱,用X中的每一個元素和平均值比較大小,這里涉及到 Numpy 的廣播機(jī)制(Broadcast)拐邪,大則為True袖订, 小則為False
X > np.average(X) # 判斷 X 的元素哪些大于平均值
## 結(jié)果如下:
array([[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[False, False, True, False, False, False],
[False, False, False, False, False, False]])
np.nonzero()的輸入?yún)?shù)為數(shù)組氮帐,返回值為相應(yīng)數(shù)組中非零元素的下標(biāo)數(shù)組,輸入的數(shù)組是幾維的洛姑,則輸出相應(yīng)個數(shù)的數(shù)組組成的tuple上沐,看下面的例子更加直觀:
# 一維數(shù)組
np.nonzero([1,0,2])
# 結(jié)果: 第0個和第2個下標(biāo)(索引)對應(yīng)的元素非0
(array([0, 2], dtype=int64),)
# 布爾值組成的一維數(shù)組
np.nonzero([True,True,False,True])
# 結(jié)果: 第0,1楞艾,3個元素為True参咙,則輸出相應(yīng)下標(biāo)組成的數(shù)組
(array([0, 1, 3], dtype=int64),)
# 二維數(shù)組
np.nonzero([[1,2,0],
[0,0,3]])
# 結(jié)果 :分別是下標(biāo)為[0,0]的1,下標(biāo)為[0,1]的2,下標(biāo)為[1,2]的3非零
# 所以輸出了第一維的下標(biāo)[0,0,1]和第二維的下標(biāo)[0, 1, 2]組成的tuple
(array([0, 0, 1], dtype=int64),
array([0, 1, 2], dtype=int64))
# 三維數(shù)組依此類推
np.nonzero([[[1,2,0],[0,0,3]],
[[0,4,0],[0,5,0]]])
# 結(jié)果:
(array([0, 0, 0, 1, 1], dtype=int64),
array([0, 0, 1, 0, 1], dtype=int64),
array([0, 1, 2, 1, 1], dtype=int64))
那么,回到這個問題产徊,是對布爾值組成的二維數(shù)組進(jìn)行 nonzero() 計算
np.nonzero(X > np.average(X))
# 得到結(jié)果:
(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))
對于二維數(shù)組,可以這樣理解蜀细,nonzero() 返回的 tuple 中舟铜,第0個數(shù)組代表的是行索引(下標(biāo)),第1個數(shù)組代表的是列索引奠衔。
取得行索引:
np.nonzero(X > np.average(X))[0]
## 取得行索引結(jié)果
array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2], dtype=int64)
由于題目的數(shù)據(jù)中谆刨,每一行代表一個城市,可以通過行索引归斤,在 cities 中找到對應(yīng)的城市痊夭,也就是:
cities[np.nonzero(X > np.average(X))[0]]
## 結(jié)果:
## array(['HongKong', 'HongKong', 'HongKong',
'HongKong', 'HongKong', 'HongKong',
'Newyork', 'Newyork', 'Newyork',
'Newyork', 'Newyork','Newyork',
'Berlin'], dtype='<U8')
再通過 set()對上面的結(jié)果集進(jìn)行去重處理,得到最終結(jié)果
set(cities[np.nonzero(X > np.average(X))[0]])
# 結(jié)果:
{'Berlin', 'HongKong', 'Newyork'}
知識點總結(jié)及參考鏈接:
numpy.average()
https://www.runoob.com/numpy/numpy-statistical-functions.html
https://numpy.org/devdocs/reference/generated/numpy.average.html#numpy.average
numpy.nonzero()
https://www.runoob.com/numpy/numpy-sort-search.html
numpy-Broadcasting
https://www.runoob.com/numpy/numpy-broadcast.html
https://www.numpy.org.cn/article/basics/python_numpy_tutorial.html#%E5%B9%BF%E6%92%AD-broadcasting
Python.set()
https://www.runoob.com/python/python-func-set.html
感謝你的閱讀脏里,希望有所收獲她我。