如何获取 numpy.random.choice 的索引?- Python

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18794390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:52:02  来源:igfitidea点击:

how to get the index of numpy.random.choice? - python

pythonrandomnumpy

提问by HappyPy

Is it possible to modify the numpy.random.choice function in order to make it return the index of the chosen element? Basically, I want to create a list and select elements randomly without replacement

是否可以修改 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))will remove the first element of the list with that value it encounters (a[1]in the example above), which may not be the chosen element (eg, a[7]).

a.remove(np.random.choice(a))将删除具有它遇到的那个值的列表的第一个元素(a[1]在上面的例子中),它可能不是被选择的元素(例如,a[7])。

采纳答案by óscar López

Here's one way to find out the indexof a randomly selected element:

这是找出随机选择元素的索引的一种方法:

import random # plain random module, not numpy's
random.choice(list(enumerate(a)))[0]
=> 4      # just an example, index is 4

Or you could retrieve the element andthe index in a single step:

或者,您可以一步检索元素索引:

random.choice(list(enumerate(a)))
=> (1, 4) # just an example, index is 1 and element is 4

回答by user2357112 supports Monica

numpy.random.choice(a, size=however_many, replace=False)

If you want a sample without replacement, just ask numpy to make you one. Don't loop and draw items repeatedly. That'll produce bloated code and horrible performance.

如果您想要一个无需更换的样品,只需让 numpy 为您制作一个。不要循环和重复绘制项目。这将产生臃肿的代码和糟糕的性能。

Example:

例子:

>>> 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])

On a sufficiently recent NumPy (at least 1.17), you should use the new randomness API, which fixes a longstanding performance issue where the old API's replace=Falsecode path unnecessarily generated a complete permutation of the input under the hood:

在足够新的 NumPy(至少 1.17)上,您应该使用新的 randomness API,它修复了一个长期存在的性能问题,旧 API 的replace=False代码路径不必要地在后台生成输入的完整排列:

rng = numpy.random.default_rng()
result = rng.choice(a, size=however_many, replace=False)

回答by CT Zhu

Regarding your first question, you can work the other way around, randomly choose from the index of the array aand then fetch the value.

关于你的第一个问题,你可以反过来工作,从数组的索引中随机选择a,然后获取值。

>>> a = [1,4,1,3,3,2,1,4]
>>> a = np.array(a)
>>> random.choice(arange(a.size))
6
>>> a[6]

But if you just need random sample without replacement, replace=Falsewill do. Can't remember when it was firstly added to random.choice, might be 1.7.0. So if you are running very old numpyit may not work. Keep in mind the default is replace=True

但是如果你只需要随机样本而不用替换,replace=False就可以了。不记得它是什么时候第一次添加到 的random.choice,可能是 1.7.0。因此,如果您运行得很老,numpy它可能无法正常工作。请记住,默认值是replace=True

回答by askewchan

Based on your comment:

根据您的评论:

The sample is already a. I want to work directly with aso that I can control how many elements are still left and perform other operations with a. – HappyPy

样本已经a。我想直接使用,a以便我可以控制剩余的元素数量并使用a. – 快乐派

it sounds to me like you're interested in working with aafter nrandomly selected elements are removed. Instead, why not work with N = len(a) - nrandomly selected elements from a? Since you want them to still be in the original order, you can select from indices like in @CTZhu's answer, but then sort them and grab from the original list:

这听起来像你对我有兴趣与工作an随机选择的元素被移除。相反,为什么不使用N = len(a) - n从 中随机选择的元素a?由于您希望它们仍按原始顺序排列,因此您可以从@CTZhu 的答案中的索引中进行选择,然后对它们进行排序并从原始列表中抓取:

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])

So now you can save that as aagain:

所以现在你可以a再次保存它:

a = a[i]

and work with awith nelements removed.

并与工作an的元素去除。

回答by lmjohns3

This is a bit in left field compared with the other answers, but I thought it might help what it sounds like you're trying to do in a slightly larger sense. You can generate a random sample without replacement by shuffling the indices of the elements in the source array :

与其他答案相比,这有点偏左,但我认为这可能有助于您在更大的意义上尝试做的事情。您可以通过改组源数组中元素的索引来生成无需替换的随机样本:

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]]

This will create a sample (here, of size 10) by drawing elements from the source set (here, of size 100) without replacement.

这将通过从源集(此处为大小 100)中绘制元素来创建一个样本(此处为 10 大小)而无需替换。

You can interact with the non-selected elements by using the remaining index values, i.e.:

您可以使用剩余的索引值与未选择的元素进行交互,即:

notsampled = source[idx[10:]]

回答by Tobias Kienzler

Instead of using choice, you can also simply random.shuffleyour array, i.e.

除了使用choice,您还可以简单地使用random.shuffle您的数组,即

random.shuffle(a)  # will shuffle a in-place

回答by Shaaban

Here is a simple solution, just choose from the range function.

这是一个简单的解决方案,只需从 range 函数中选择即可。

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]))

回答by Mehdi Saman Booy

Maybe late but it worth to mention this solution because I think the simplest way to do so is:

也许晚了,但值得一提的是这个解决方案,因为我认为最简单的方法是:

a = [1,4,1,3,3,2,1,4]
n = len(a)
idx = np.random.choice(list(range(n)), p=np.ones(n)/n)

It means you are choosing from the indicesuniformly. In a more general case, you can do a weighted sampling (and return the index) in this way:

这意味着您从索引中统一选择。在更一般的情况下,您可以通过这种方式进行加权采样(并返回索引):

probs = [.3, .4, .2, 0, .1]
n = len(a)
idx = np.random.choice(list(range(n)), p=probs)

If you try to do so for so many times (e.g. 1e5), the histogram of the chosen indices would be like [0.30126 0.39817 0.19986 0. 0.10071]in this case which is correct.

如果您多次尝试这样做(例如 1e5),则所选索引的直方图将类似于[0.30126 0.39817 0.19986 0. 0.10071]在这种情况下是正确的。

Anyway, you should choose from the indices and use the values (if you need) as their probabilities.

无论如何,您应该从索引中进行选择并使用这些值(如果需要)作为它们的概率。