python 如何在list中找Topk的數(shù)值和索引
需求:
對(duì)于一個(gè)python list 或者numpy數(shù)組,我需要找到這個(gè)list中最大的K個(gè)數(shù)及其對(duì)應(yīng)的下標(biāo)。
解決方式:
1. 可以構(gòu)造字典通過(guò)排序解決,不過(guò)代碼量較多。
2. 使用heapq庫(kù),可以直接獲取最大值的下標(biāo)和數(shù)值。
import heapq a = [4,2,6,1,9,9] # 獲取下標(biāo), 輸出為[4, 5, 2] heapq.nlargest(3, range(len(a)), a.__getitem__) # 獲取數(shù)值, 輸出為[9, 9, 6] heapq.nlargest(3,a)
如果要取最小的數(shù),使用 nsmallest即可
補(bǔ)充:Python 利用中間值求TopK 算法
算法思想
首先我們要思考,我要做什么?解決什么問(wèn)題?
TopK問(wèn)題,找出一組數(shù)據(jù)中的前K個(gè)最大值或者最小值,這個(gè)數(shù)據(jù)是否重復(fù)?要做去重處理?
ok 我們明確我們做什么了 ,那介紹的python處理的topK 算法過(guò)程是怎么樣的呢?
如果用排序那就沒(méi)必要引入topK 了,當(dāng)數(shù)據(jù)強(qiáng)大的時(shí)候選取TopK 可以省略很多排序的計(jì)算,至于有多優(yōu)化自己去思考下,就比如排列組合的C,A的區(qū)別,一個(gè)是抽取,一個(gè)是抽取并排列…
以下以找出TopK 的最大值為例,最小值的可以自己修改一下下就可以
介紹的算法思想是利用中間值,將數(shù)列分為三部分 ,
【比中間值大的列表】,中間值,【比中間值小的列表】
那么我們當(dāng)比較
【比中間值大的列表】的個(gè)數(shù) == k
的時(shí)候就可以得出前K個(gè)最大值了,因此
重點(diǎn)就是找出這個(gè)中間值
如何找出中間值
以列表的第一個(gè)數(shù)開(kāi)始為中間值,拆分為三部分
if 【比中間值大的列表】的個(gè)數(shù) == k:return 中間值 #程序出口,結(jié)束。
if 【比中間值大的列表】的個(gè)數(shù) < k :
·····繼續(xù)在【比中間值小的列表】找
·····K - 【比中間值大的列表】的個(gè)數(shù) -1 個(gè)數(shù)
(為什么要減一,1是前一次的中間值,分的三部分,前部分后部分都沒(méi)有包含中間值,因此…)
if 【比中間值大的列表】的個(gè)數(shù) > k :
…也就是說(shuō)比中間值大的列表比K還大,那就在這個(gè)列表中繼續(xù)找就行
結(jié)合代碼和注釋看
如果要找最小值,只需要改一下就ok ,還可以設(shè)置一個(gè)布爾值的輸入,來(lái)做前K個(gè)最大值最小值
#2019 11 04
#author 半斤地瓜燒
#TopK 算法,找出序列中前K個(gè)最大值的
#輸入一個(gè)seq
# 輸出以seq[0]為中間值 劃分的三個(gè)部分,中間值,比這個(gè)值大的seq ,比這個(gè)值小的seq,
# 即splitNum,theBig,theSmall
def Split_Seq(seq):
splitNum = seq[0]
seq = seq[1:]#兩個(gè)部分都不包含中間值,因此切片去除seq[0]
theBig = [x for x in seq if x >= splitNum]
theSmall = [x for x in seq if x < splitNum]
return splitNum,theBig,theSmall
#找出中間值
def topKNum(seq,k):
splitNum, theBig, theSmall = Split_Seq(seq)
theBigLen = len(theBig)
if k == theBigLen:
return splitNum#出口,返回這個(gè)中間值,
# 為什么不直接返回thebig?因?yàn)榇嬖谶f歸的原因thebig 不是在初始的seq找出來(lái)的
#需要重新Split,即可,讀者自己思考
# 大值的列表中還未夠K個(gè)數(shù)的情況,
if k > theBigLen:
return topKNum(theSmall,k-theBigLen-1)
# 大值的列表中大于K個(gè)數(shù)的情況
return topKNum(theBig,k)
#由中間值找出TopK個(gè)值,<list>
def getTopK(seq,k):
return [i for i in seq if i > topKNum(seq, k)]
if __name__ == '__main__':
alist = [7, 3, 5, 1,885,234,2211,222,22, 2, 11, 2, 115]
print("===為了驗(yàn)證,引入排序觀(guān)看===", sorted(alist,reverse= True))
print(getTopK(alist, 3))
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python利用百度AI實(shí)現(xiàn)文字識(shí)別功能
這篇文章主要為大家詳細(xì)介紹了python利用百度AI實(shí)現(xiàn)文字識(shí)別,主要涉及通用文字識(shí)別、網(wǎng)絡(luò)圖片文字識(shí)別、身份證識(shí)別等文字識(shí)別功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Python設(shè)計(jì)模式之工廠(chǎng)方法模式實(shí)例詳解
這篇文章主要介紹了Python設(shè)計(jì)模式之工廠(chǎng)方法模式,結(jié)合實(shí)例形式較為詳細(xì)的分析了工廠(chǎng)方法模式的概念、原理、用法及相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
使用pandas或numpy處理數(shù)據(jù)中的空值(np.isnan()/pd.isnull())
這篇文章主要介紹了使用pandas或numpy處理數(shù)據(jù)中的空值(np.isnan()/pd.isnull()),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
詳解sklearn?Preprocessing?數(shù)據(jù)預(yù)處理功能
這篇文章主要介紹了sklearn?Preprocessing?數(shù)據(jù)預(yù)處理功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
使用python?matplotlib畫(huà)折線(xiàn)圖實(shí)例代碼
Matplotlib是一個(gè)Python工具箱,用于科學(xué)計(jì)算的數(shù)據(jù)可視化,下面這篇文章主要給大家介紹了關(guān)于如何使用python?matplotlib畫(huà)折線(xiàn)圖的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
python使用turtle庫(kù)繪制奧運(yùn)五環(huán)
turtle也叫海龜,是turtle繪圖體系的python實(shí)現(xiàn),這篇文章主要介紹了python使用turtle庫(kù)繪制奧運(yùn)五環(huán),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-02-02
Django+Vue實(shí)現(xiàn)文件上傳下載的項(xiàng)目實(shí)踐
本文主要介紹了Django+Vue實(shí)現(xiàn)文件上傳下載的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
Python的Tornado框架實(shí)現(xiàn)異步非阻塞訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的示例
Tornado框架的異步非阻塞特性是其最大的亮點(diǎn),這里我們將立足于基礎(chǔ)來(lái)介紹一種簡(jiǎn)單的Python的Tornado框架實(shí)現(xiàn)異步非阻塞訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的示例:2016-06-06

