Python 在NumPy数组中记录迄今为止的最小值

Python 在NumPy数组中记录迄今为止的最小值,python,arrays,numpy,Python,Arrays,Numpy,假设我有一个NumPy数组,如: import numpy as np x = np.array([1, 5, 4, 2, 3, 6, 7, 5, np.inf, np.inf, np.inf, 4, 2, 8, 3, 5, 9, 2, 3, 4]) 从i=9开始,我想沿着i=0遍历每个元素,然后记录“迄今为止最小的”数字以及这些数字的索引。在本例中: left_val = [] left_idx = [] min_so_far = np.inf for i in range(9, -1,

假设我有一个NumPy数组,如:

import numpy as np

x = np.array([1, 5, 4, 2, 3, 6, 7, 5, np.inf, np.inf, np.inf, 4, 2, 8, 3, 5, 9, 2, 3, 4])
i=9
开始,我想沿着
i=0
遍历每个元素,然后记录“迄今为止最小的”数字以及这些数字的索引。在本例中:

left_val = []
left_idx = []
min_so_far = np.inf
for i in range(9, -1, -1):
    if x[i] < min_so_far:
        left_val.append(x[i])
        left_idx.append(i)
        min_so_far = x[i]
到目前为止,正确的最小值是
[4,2]
,它们位于索引
[11,12]


x
的长度大得多时,有没有更快的方法来执行此
min\u so\u far
搜索?

这不是您想要的,但它会在遍历数组时为所有子列表提供最小值。它是pythonic的,但对于大小合理的numpy阵列来说,速度会很慢

right_going = [min(x[n:i]) for i in range(n, len (x))]
left_going = [min(x[(n-i):n]) for i in range(n)]

值为最小值的数组索引在第一种情况下为
n+list\u index
,在第二种情况下仅为列表的索引。然后,通过获取这些列表中第一次(或最后一次)重复值的索引和值,您可以完全按照自己的意愿进行操作。

您可以执行以下操作:

def right_mins(x):
    y = np.minimum.accumulate(x)
    idx = np.flatnonzero(np.r_[1, np.diff(y)])
    y = x[idx]
    mask = np.isfinite(y)
    return y[mask], idx[mask]

def left_mins(x):
    y, idx = right_mins(x[::-1])
    return y, x.size - 1 - idx
您可以将这些函数直接应用于所需的切片,例如:

>>> left_mins(x[:10])
(array([5., 3., 2., 1.]), array([7, 4, 3, 0]))
>>> n, i = right_mins(x[9:])
>>> n, i + 9
(array([4., 2.]), array([11, 12]))

你能澄清一下你的预期产出是什么吗?因为你的电流只有一个值和它的索引,但是你的解释似乎暗示了输出中有几个值。我已经添加了两种算法产生的输出,可能是Spythonic,但肯定不是numpythonic@MadPhysicist,考虑到这个问题的顺序性,“numpythonic”(ugg!)可能是不可能的
np.minimum.acculate
获取各种范围的最小值,但我认为没有
acculate
版本的
argmin
。熊猫有什么有用的吗?@hpaulj。我已经发布了一个带有矢量化解决方案的答案。当然没有argmin.acculate,但是通常的diff技巧在minimum.acculate之后效果很好。可能我误解了什么,但是
left_mins(x)
在我提供与问题相同的
x
时,似乎只返回
(数组([1.])、数组([0])
。相反,
left_mins
需要返回
(数组([5,3,2,1])、数组([7,4,3,0]))
@slaw需要将函数应用于数组的相关部分<代码>右分钟([x[:10])和
左分钟([x[10:])
。然后两者都需要删除inf值和相应的索引。np.inf是第一次找到它时的最小值。@slaw。我添加了几个示例,演示如何运行确切的用例。如果要对数组进行子集划分,需要将最左边索引的偏移量添加到结果中
>>> left_mins(x[:10])
(array([5., 3., 2., 1.]), array([7, 4, 3, 0]))
>>> n, i = right_mins(x[9:])
>>> n, i + 9
(array([4., 2.]), array([11, 12]))