Python ndarray中最大值的索引列表
我有一个约会。从这个数组中,我需要选择具有最大值的N个数字的列表。我找到了Python ndarray中最大值的索引列表,python,numpy,indexing,Python,Numpy,Indexing,我有一个约会。从这个数组中,我需要选择具有最大值的N个数字的列表。我找到了heapq.nlargest来查找N个最大的条目,但我需要提取索引。 我想构建一个新的数组,其中只有第一列中权重最大的N行能够存活。其余行将替换为随机值 import numpy as np import heapq # For choosing list of max values a = [[1.1,2.1,3.1], [2.1,3.1,4.1], [5.1,0.1,7.1],[0.1,1.1,1.1],[4.1,
heapq.nlargest
来查找N个最大的条目,但我需要提取索引。
我想构建一个新的数组,其中只有第一列中权重最大的N行能够存活。其余行将替换为随机值
import numpy as np
import heapq # For choosing list of max values
a = [[1.1,2.1,3.1], [2.1,3.1,4.1], [5.1,0.1,7.1],[0.1,1.1,1.1],[4.1,3.1,9.1]]
a = np.asarray(a)
maxVal = heapq.nlargest(2,a[:,0])
if __name__ == '__main__':
print a
print maxVal
我得到的结果是:
[[ 1.1 2.1 3.1]
[ 2.1 3.1 4.1]
[ 5.1 0.1 7.1]
[ 0.1 1.1 1.1]
[ 4.1 3.1 9.1]]
[5.0999999999999996, 4.0999999999999996]
但我需要的是[2,4]
作为构建新数组的索引。索引是行,因此在本例中,如果我想用0替换其余的,我需要用以下内容结束:
[[0.0 0.0 0.0]
[ 0.0 0.0 0.0]
[ 5.1 0.1 7.1]
[ 0.0 0.0 0.0]
[ 4.1 3.1 9.1]]
我被困在需要索引的地方。原始数组有1000行和100列。权重是标准化的浮点,如果a[:,1]==maxVal[0]:的话,我不想做类似于的事情,因为有时我的权重非常接近,并且可以使用比原始N更多的值maxVal[0]
有没有简单的方法可以在此设置中提取索引以替换数组的其余部分?如果只有1000行,我会忘记堆,并在第一列使用np.argsort
:
>>> np.argsort(a[:,0])[::-1][:2]
array([2, 4])
如果你想把它们放在一起,它看起来会像:
def trim_rows(a, n) :
idx = np.argsort(a[:,0])[:-n]
a[idx] = 0
>>> a = np.random.rand(10, 4)
>>> a
array([[ 0.34416425, 0.89021968, 0.06260404, 0.0218131 ],
[ 0.72344948, 0.79637177, 0.70029863, 0.20096129],
[ 0.27772833, 0.05372373, 0.00372941, 0.18454153],
[ 0.09124461, 0.38676351, 0.98478492, 0.72986697],
[ 0.84789887, 0.69171688, 0.97718206, 0.64019977],
[ 0.27597241, 0.26705301, 0.62124467, 0.43337711],
[ 0.79455424, 0.37024814, 0.93549275, 0.01130491],
[ 0.95113795, 0.32306471, 0.47548887, 0.20429272],
[ 0.3943888 , 0.61586129, 0.02776393, 0.2560126 ],
[ 0.5934556 , 0.23093912, 0.12550062, 0.58542137]])
>>> trim_rows(a, 3)
>>> a
array([[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0.84789887, 0.69171688, 0.97718206, 0.64019977],
[ 0. , 0. , 0. , 0. ],
[ 0.79455424, 0.37024814, 0.93549275, 0.01130491],
[ 0.95113795, 0.32306471, 0.47548887, 0.20429272],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ]])
对于您的数据大小,它可能足够快:
In [7]: a = np.random.rand(1000, 100)
In [8]: %timeit -n1 -r1 trim_rows(a, 50)
1 loops, best of 1: 7.65 ms per loop
如果只有1000行,我会忘记堆,在第一列使用np.argsort
:
>>> np.argsort(a[:,0])[::-1][:2]
array([2, 4])
如果你想把它们放在一起,它看起来会像:
def trim_rows(a, n) :
idx = np.argsort(a[:,0])[:-n]
a[idx] = 0
>>> a = np.random.rand(10, 4)
>>> a
array([[ 0.34416425, 0.89021968, 0.06260404, 0.0218131 ],
[ 0.72344948, 0.79637177, 0.70029863, 0.20096129],
[ 0.27772833, 0.05372373, 0.00372941, 0.18454153],
[ 0.09124461, 0.38676351, 0.98478492, 0.72986697],
[ 0.84789887, 0.69171688, 0.97718206, 0.64019977],
[ 0.27597241, 0.26705301, 0.62124467, 0.43337711],
[ 0.79455424, 0.37024814, 0.93549275, 0.01130491],
[ 0.95113795, 0.32306471, 0.47548887, 0.20429272],
[ 0.3943888 , 0.61586129, 0.02776393, 0.2560126 ],
[ 0.5934556 , 0.23093912, 0.12550062, 0.58542137]])
>>> trim_rows(a, 3)
>>> a
array([[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 0.84789887, 0.69171688, 0.97718206, 0.64019977],
[ 0. , 0. , 0. , 0. ],
[ 0.79455424, 0.37024814, 0.93549275, 0.01130491],
[ 0.95113795, 0.32306471, 0.47548887, 0.20429272],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ]])
对于您的数据大小,它可能足够快:
In [7]: a = np.random.rand(1000, 100)
In [8]: %timeit -n1 -r1 trim_rows(a, 50)
1 loops, best of 1: 7.65 ms per loop
首先检索N
最后的数字,然后将其反转,而不是反转整个列表,成本可能更低。类似于np.argsort(a[:,0])[-2:][::-1]
@entropy它们基本上都是零成本操作,因为没有实际的数据混乱发生,只是移动了步幅、形状和指针。使用a=np.arange(10**6)
我得到了以下计时:在[23]:%timeit a[-2:][:-1]1000000个循环中,每个循环最好3:740ns
和在[24]:%timeit a[:-1][:2]1000000个循环中,每个循环最好3:731ns
。你可能是对的,我不知道python的列表实现是如何工作的。如果它实际上没有反转底层数组,只需更改步幅和开始/结束指针,那么您绝对是正确的right@entropyPython列表确实需要花费一定的代价来扭转它们,然后您的观察结果就会准确无误。同样使用a=range(10**6)
这些是计时:在[26]:%timeit a[:-1][:2]100个循环中,每个循环的最佳时间为3:9.54毫秒
和在[27]:%timeit a[-2:[:-1]1000000个循环中,每个循环的最佳时间为3:333纳秒
,因此您的方法比[27]快30000倍。它不适用于numpy数组。啊,我忽略了np.argsort()
返回numpy数组的事实。我的错误:)首先检索N
最后的数字,然后将其反转,而不是反转整个列表,成本可能会更低。类似于np.argsort(a[:,0])[-2:][::-1]
@entropy它们基本上都是零成本操作,因为没有实际的数据混乱发生,只是移动了步幅、形状和指针。使用a=np.arange(10**6)
我得到了以下计时:在[23]:%timeit a[-2:][:-1]1000000个循环中,每个循环最好3:740ns
和在[24]:%timeit a[:-1][:2]1000000个循环中,每个循环最好3:731ns
。你可能是对的,我不知道python的列表实现是如何工作的。如果它实际上没有反转底层数组,只需更改步幅和开始/结束指针,那么您绝对是正确的right@entropyPython列表确实需要花费一定的代价来扭转它们,然后您的观察结果就会准确无误。同样使用a=range(10**6)
这些是计时:在[26]:%timeit a[:-1][:2]100个循环中,每个循环的最佳时间为3:9.54毫秒
和在[27]:%timeit a[-2:[:-1]1000000个循环中,每个循环的最佳时间为3:333纳秒
,因此您的方法比[27]快30000倍。它不适用于numpy数组。啊,我忽略了np.argsort()
返回numpy数组的事实。我的错:)