提问人:HappyPy 提问时间:9/14/2013 更新时间:5/10/2022 访问量:54709
如何获取numpy.random.choice的索引?-蟒
how to get the index of numpy.random.choice? - python
问:
是否可以修改 numpy.random.choice 函数以使其返回所选元素的索引? 基本上,我想创建一个列表并随机选择元素而无需替换
import numpy as np
>>> a = [1,4,1,3,3,2,1,4]
>>> np.random.choice(a)
>>> 4
>>> a
>>> [1,4,1,3,3,2,1,4]
a.remove(np.random.choice(a))
将删除列表中的第一个元素,该元素具有它遇到的值(在上面的示例中),该元素可能不是所选元素(例如,)。a[1]
a[7]
答:
以下是找出随机选择元素的索引的一种方法:
import random # plain random module, not numpy's
random.choice(list(enumerate(a)))[0]
=> 4 # just an example, index is 4
或者,您可以在一个步骤中检索元素和索引:
random.choice(list(enumerate(a)))
=> (1, 4) # just an example, index is 1 and element is 4
评论
list(enumerate(a))
生成一个元组列表,该表被视为类似 2D 数组的对象。这是行不通的。
random.choice
np.random.choice
np.random.choice
random.choice
random
numpy.random.choice(a, size=however_many, replace=False)
如果您想要一个没有更换的样品,只需让 numpy 为您制作一个。不要重复循环和绘制项目。这将产生臃肿的代码和糟糕的性能。
例:
>>> a = numpy.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> numpy.random.choice(a, size=5, replace=False)
array([7, 5, 8, 6, 2])
在足够新的 NumPy(至少 1.17)上,您应该使用新的随机性 API,它修复了一个长期存在的性能问题,即旧 API 的代码路径不必要地在后台生成输入的完整排列:replace=False
rng = numpy.random.default_rng()
result = rng.choice(a, size=however_many, replace=False)
评论
a
size
replace=False
(however_many,)
a
a
a
a
关于你的第一个问题,你可以反过来做,从数组的索引中随机选择,然后获取值。a
>>> a = [1,4,1,3,3,2,1,4]
>>> a = np.array(a)
>>> random.choice(arange(a.size))
6
>>> a[6]
但是,如果您只需要随机样本而不需要替换,那就可以了。不记得它是什么时候第一次添加到的,可能是 1.7.0。因此,如果您运行得很旧,它可能不起作用。请记住,默认值为replace=False
random.choice
numpy
replace=True
评论
np.random.randint(0,a.size)
np.random.randint(0,a.size, size=size_you_want)
a
array
array
replace=False
根据您的评论:
示例已经是 .我想直接使用 ,这样我就可以控制还剩下多少元素并使用 .– 快乐派
a
a
a
在我看来,您有兴趣在删除随机选择的元素后使用。相反,为什么不使用从中随机选择的元素呢?由于您希望它们仍按原始顺序排列,因此您可以像@CTZhu的答案一样从索引中进行选择,然后对它们进行排序并从原始列表中抓取:a
n
N = len(a) - n
a
import numpy as np
n = 3 #number to 'remove'
a = np.array([1,4,1,3,3,2,1,4])
i = np.random.choice(np.arange(a.size), a.size-n, replace=False)
i.sort()
a[i]
#array([1, 4, 1, 3, 1])
所以现在你可以再次保存它:a
a = a[i]
并使用删除的元素。a
n
与其他答案相比,这有点偏左,但我认为它可能会有所帮助,听起来你正在尝试在更大的意义上做。您可以通过对源数组中元素的索引进行洗牌来生成一个随机样本,而无需替换:
source = np.random.randint(0, 100, size=100) # generate a set to sample from
idx = np.arange(len(source))
np.random.shuffle(idx)
subsample = source[idx[:10]]
这将通过从源集(此处为 100 号)中绘制元素来创建一个样本(此处为 100 号),而无需替换。
您可以使用剩余的索引值与未选定的元素进行交互,即:
notsampled = source[idx[10:]]
除了使用 ,您还可以简单地 random.shuffle
您的数组,即choice
random.shuffle(a) # will shuffle a in-place
这是一个简单的解决方案,只需从范围函数中进行选择即可。
import numpy as np
a = [100,400,100,300,300,200,100,400]
I=np.random.choice(np.arange(len(a)))
print('index is '+str(I)+' number is '+str(a[I]))
也许晚了,但值得一提的是这个解决方案,因为我认为最简单的方法是:
a = [1, 4, 1, 3, 3, 2, 1, 4]
n = len(a)
idx = np.random.choice(list(range(n)), p=np.ones(n)/n)
这意味着您正在统一地从指数中进行选择。在更一般的情况下,您可以通过以下方式进行加权抽样(并返回索引):
probs = [.3, .4, .2, 0, .1]
n = len(a)
idx = np.random.choice(list(range(n)), p=probs)
如果您尝试这样做很多次(例如 1e5),所选索引的直方图将像在这种情况下一样,这是正确的。[0.30126 0.39817 0.19986 0. 0.10071]
无论如何,您应该从指数中进行选择并使用值(如果需要)作为它们的概率。
问题标题与其描述略有不同。我只是想要标题问题的答案,它只从中获取一个(整数)索引。而不是上述任何一种,我决定(在numpy 1.21.6中测试)。numpy.random.choice()
index = numpy.random.choice(len(array_or_whatever))
前任:
import numpy
a = [1, 2, 3, 4]
i = numpy.random.choice(len(a))
我在其他解决方案中遇到的问题是不必要的转换,这将在新对象中重新创建整个集合(慢!list
文档中关于第一个参数的关键点:a
a
:类一维数组或 int 如果是 ndarray,则从其元素生成随机样本。如果为 int,则生成随机样本,就好像它是 np.arange(a) 一样
由于这个问题很老了,那么我可能是出于新版本的便利性,而这些版本恰好支持我自己和 OP 想要的东西。
评论
enumerate
可能会起作用