Python 如何编写NumPy argmode()?

Python 如何编写NumPy argmode()?,python,math,numpy,Python,Math,Numpy,我知道argmax()返回沿轴的最大值的索引 我还知道,在最大值多次出现的情况下,将返回与第一次出现对应的索引 argmax()。如何编写numpy.argmode()函数 换句话说,如何编写一个计算numpy数组中的模式值并获取第一次出现的索引的函数 每个人都知道不存在numpy.argmode,但这样一个函数的功能正是我所追求的 我知道该模式会多次出现。我们应该能够让它像argmax一样工作,如果我们有多个实例,它只返回第一个实例的值和索引 我想要的一个例子是: a = numpy.arra

我知道
argmax()
返回沿轴的最大值的索引

我还知道,在最大值多次出现的情况下,将返回与第一次出现对应的索引

argmax()。如何编写numpy.argmode()函数

换句话说,如何编写一个计算numpy数组中的模式值并获取第一次出现的索引的函数

每个人都知道不存在numpy.argmode,但这样一个函数的功能正是我所追求的

我知道该模式会多次出现。我们应该能够让它像argmax一样工作,如果我们有多个实例,它只返回第一个实例的值和索引

我想要的一个例子是:

a = numpy.array([ 6, 3, 4, 1, 2, 2, 2])
numberIWant = numpy.argmode(a)
print(numberIWant)
# should print 4 (the index of the first occurrence of the mode)
我尝试使用:

stats.mode(a)[0][0]
numpy.argwhere(a==num)[0][0]
这确实有效,但我正在寻找一个更高效、更简洁的解决方案。
有什么想法吗

是什么让一个解决方案比另一个更“优雅”?矮小?速度聪明?最像蟒蛇?努比

对我来说,速度比紧凑更重要。通过将解决方案包装在函数调用中,我总能使其更紧凑。实际上,健壮性更为重要


非numpy路线是在
集合中使用方便的工具,如图所示:

In [342]: a = numpy.array([ 6, 3, 4, 1, 2, 2, 2])

In [343]: import collections
使用
计数器
快速获取模式(值):

使用
defaultdict
收集所有值的位置:

In [349]: adict=collections.defaultdict(list)
In [350]: for i,v in enumerate(a):
    adict[v].append(i)
In [351]: adict[mode]
Out[351]: [4, 5, 6]
我本可以在
adict
中搜索最长的列表,但我怀疑
计数器的速度更快

实际上,当我知道
模式
时,我所需要的就是
其中
——正如您使用
统计数据
所显示的:

In [352]: np.where(a==mode)
Out[352]: (array([4, 5, 6], dtype=int32),)
在对这个小阵列进行时间测试时,
计数器
获胜

In [358]: timeit stats.mode(a)[0][0]
1000 loops, best of 3: 337 µs per loop
In [359]: timeit collections.Counter(a).most_common(1)[0][0]
10000 loops, best of 3: 20 µs per loop
另一种可能的工具是
bincount

In [367]: np.bincount(a)
Out[367]: array([0, 1, 3, 1, 1, 0, 1], dtype=int32)
In [368]: timeit np.argmax(np.bincount(a))
100000 loops, best of 3: 3.29 µs per loop
中的

In [373]: timeit np.where(a==np.argmax(np.bincount(a)))[0][0]
100000 loops, best of 3: 11.2 µs per loop

它很快,但我不确定它是否足够通用。

如果您想留在NumPy,您可以使用的一些额外回报来获得您想要的:

>>> _, idx, cnt = np.unique(a, return_index=True, return_counts=True)
>>> idx[np.argmax(cnt)]
4
编辑


提供一些关于正在发生的事情的上下文
np.unique
始终返回唯一值的排序数组。可选的
return\u index
提供了另一个输出数组,其中包含每个唯一值第一次出现的索引。可选的
return\u counts
提供了一个额外的输出,其中包含每个唯一值的出现次数。有了这些构建块,您所需要做的就是将索引数组的项返回到发生最高计数的位置。

我想说您拥有的看起来不错,但是
scipy.stats.mode
似乎有a,对于一维
len(a)*len(set(a))
而言,时间与
len(a)*len len set(a)成比例。计算scipy.stats.mode(numpy.arange(100000))花费了27.6秒
。除此之外,计算模式的自然方法似乎不像同时跟踪索引那样会提高效率,因此再次传递索引似乎很好。参考
numpy.argmode
,好像真的有这样一个numpy函数,这是令人困惑的。并没有这样的函数,即使您编写了它,也可能不想将其添加到模块中。在任何情况下,“mode”都是一个笨拙的统计数据,它不像
sum
mean
max
等那样工作。查看stats.mode的代码是正确的,numpy.argmode不存在。我想说的是没有argmode,但是我为这样一个函数寻找一些源代码。我将其与numpy的fft算法结合使用,并尝试检索录制时麦克风拾取的模式频率。目前,它只拾取最大值,这是大多数解决方案所做的。但这并不理想,因为这并没有考虑到“噪音”或对我想要拾取的频率的干扰。这里有这么多好的东西-希望我六个月前就看到了!哇,这真是太棒了!谢谢你!今天晚些时候,我将与我的合作伙伴一起尝试,并将其标记为有效的解决方案。我毫不怀疑它会的!我澄清了优雅。谢谢你帮我澄清。为我工作。谢谢我想那会管用的。如果我错了,请纠正我。您是否首先获得每个值的计数?然后,您是否使用最大计数(即模式值)获取该值并返回其索引?对不起,我只是想了解这里发生了什么。Looks Beauty今天晚些时候会尝试它,并检查它是否有效:)是的,基本上就是这样,在答案中添加了一些解释,希望它有意义。对我有效。谢谢
>>> _, idx, cnt = np.unique(a, return_index=True, return_counts=True)
>>> idx[np.argmax(cnt)]
4