Python 有没有一种快速方法可以将numpy数组中的一个元素与该数组中的其余元素进行比较?

Python 有没有一种快速方法可以将numpy数组中的一个元素与该数组中的其余元素进行比较?,python,arrays,numpy,Python,Arrays,Numpy,我有一个数组,我想看看该数组中的任何元素是否大于或等于该数组中的任何其他元素。我可以做两个for循环,但我的数组长度为10000或更大,因此创建了一个非常慢的程序。不管怎样,我能做得更快吗 [编辑]我只需要查看它是否大于或等于我正在查看的元素后面的元素,如果大于或等于,我需要知道它的索引 [编辑] 我将更清楚地重新解释我的问题,因为目前的解决方案无法满足我的需要。首先,这里有一些代码 x=linspace(-10, 10, 10000) t=linspace(0,5,10000) u=np.e

我有一个数组,我想看看该数组中的任何元素是否大于或等于该数组中的任何其他元素。我可以做两个for循环,但我的数组长度为10000或更大,因此创建了一个非常慢的程序。不管怎样,我能做得更快吗

[编辑]我只需要查看它是否大于或等于我正在查看的元素后面的元素,如果大于或等于,我需要知道它的索引

[编辑] 我将更清楚地重新解释我的问题,因为目前的解决方案无法满足我的需要。首先,这里有一些代码

x=linspace(-10, 10, 10000)
t=linspace(0,5,10000)

u=np.exp(-x**2)

k=u*t+x
我取一个x数组,把它放到高斯函数中,得到它的高度,然后基于这个高度,就是x值在空间中传播的速度,我用k求出。我的问题是,我需要找出高斯函数何时变成双值函数(或者换句话说,当冲击发生时)。如果我使用argmax解决方案,我将始终得到k中的最后一个值,因为它非常接近于零,我需要元素后面的第一个值,它将在函数中给我一个双倍值

[编辑]小示例

x=[0,1,2,3,4,5,6,7,8,9,10] #Input 
k=[0,1,2,3,4,5,6,5,4,10] #adjusted for speed

output I want
in this case, 5 is the first number that goes above a number that comes after it.
So I need to know the index of where 5 is located and possibly the index 
of the number that it is greater than

矢量化解决方案,比ecatmur快约25%:

np.where(k > np.min(k[np.where(np.diff(k) < 0)[0][0]:]))[0][0]
编辑 实际上,使用10000项python for循环比在100000000项数组上操作要便宜:

In [14]: np.where(np.array([True if np.all(k[:j] <= k[j]) else
                            False for j in xrange(len(k))]) == 0)
Out[14]: (array([5129, 5130, 5131, ..., 6324, 6325, 6326]),)

In [15]: %timeit np.where(np.array([True if np.all(k[:j] <= k[j]) else
                                    False for j in xrange(len(k))]) == 0)
1 loops, best of 3: 201 ms per loop
位置
[i,j]
中的项目告诉您
k[j]
是否小于或等于
k[:i]
中的所有项目。如果取该矩阵的对角线:

>>> np.cumprod(k <= k[:, None], axis=1)[np.diag_indices(k.shape[0])]
array([1, 1, 1, ..., 1, 1, 1])
您将拥有满足您所需条件的所有值的索引

如果您只对第一个感兴趣:

>>> np.argmax(np.cumprod(k <= k[:, None],
...                      axis=1)[np.diag_indices(k.shape[0])] == 0)
5129

>>np.argmax(np.cumprod(k大于后面值的第一个值必然对应于局部极小值中的最小值:

k = np.array([0,1,2,3,4,5,6,5,4,10])
lm_i = np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1
mlm = np.min(k[lm_i])
mlm_i = lm_i[np.argmin(k[lm_i])]
第一个值大于后一个值的索引是大于该最小局部最小值的第一个索引:

i = np.where(k > mlm)[0][0]

(忽略图形在切线处似乎与水平线相交;这只是一个显示伪影。)

作为一个班轮:

np.where(k > np.min(k[np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1]))[0][0]
请注意,这比root的解决方案快约1000倍,因为它是完全矢量化的:

%timeit np.where(k > np.min(k[np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1]))[0][0]
1000 loops, best of 3: 228 us per loop

你能更准确地描述你的问题吗?目前你可以简单地
打印“Yes”
,因为数组中的某个元素实际上大于或等于所有其他元素。你是否试图找到最大元素?我想最大的事情是在我知道它大于一个正在进行的元素后找到索引。让我来看看尝试重申您的问题:给定列表
A
和索引
I
,确定
A[I]
大于
A
中的所有后续值。如果不是,请确定
A
中最大后续值的索引。是吗?是的,正是这样。仍然不确定OP要求的是什么,但它肯定看起来像
arr[i::]argmax()
是解决方案。请看我编辑的问题,看看为什么这对我不起作用。不过,我确实学到了一些东西,因此我感谢您。@NightHallow--即使是您当前的编辑,理解您试图完成的任务也要花费相当大的成本。请给我们一个小的输入示例(例如长度10)然后添加你想要的输出并解释…@NightHallow——这是你想要的输出,还是你只想要大于其直接后继者的索引——在这种情况下,它更简单……我有直接后继者的代码,所以这就是我要找的。你的编辑给了我一个错误,它与存在有关在一个错误的地方?我无法让它工作。现在就可以了!但是我接受的解决方案比我需要它的效果好一点,但是我很可能也会将这个解决方案用于我计划的一些不同的事情。谢谢!@NightHallow ecatmur的答案显然是正确的:好的数学总是胜过编程。令人惊讶的是,这是到目前为止最好的解决方案测试解决方案。我不得不添加一个try-except块,因为我得到了值错误,但在那之后它工作得非常好。谢谢!你可以使用
np.where(k>np.min(k[np.where(np.diff(k)<0)[0]:])[0][0]
另外,你也不需要
np.min()
call.@如果可能存在多个局部极小值,则必须使用
np.min
根。不过,我喜欢你的解决方案;你在第一个局部极大值之后找到全局极小值,这比考虑多个局部极小值要简单得多。
In [3]: %timeit np.argmax(np.cumprod(k <= k[:, None],
                                     axis=1)[np.diag_indices(k.shape[0])] == 0)
1 loops, best of 3: 948 ms per loop
k = np.array([0,1,2,3,4,5,6,5,4,10])
lm_i = np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1
mlm = np.min(k[lm_i])
mlm_i = lm_i[np.argmin(k[lm_i])]
i = np.where(k > mlm)[0][0]
np.where(k > np.min(k[np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1]))[0][0]
%timeit np.where(k > np.min(k[np.where(np.diff(np.sign(np.diff(k))) > 0)[0] + 1]))[0][0]
1000 loops, best of 3: 228 us per loop