Python 在NumPy数组中记录迄今为止的最小值
假设我有一个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,
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]))