编辑
实际上,拥有 10,000 项 python for 循环比在 100,000,000 项数组上操作更便宜::
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
就内存而言,这将是昂贵的,但您可以使用广播对搜索进行矢量化。如果你这样做:
>>> k <= k[:, None]
array([[ True, False, False, ..., False, False, False],
[ True, True, False, ..., False, False, False],
[ True, True, True, ..., False, False, False],
...,
[ True, True, True, ..., True, False, False],
[ True, True, True, ..., True, True, False],
[ True, True, True, ..., True, True, True]], dtype=bool)
返回值是一个布尔数组,其中位置项[i, j]
告诉您是否k[j]
小于或等于k[i]
。什么时候可以使用np.cumprod
如下:
>>> np.cumprod(k <= k[:, None], axis=1)
array([[1, 0, 0, ..., 0, 0, 0],
[1, 1, 0, ..., 0, 0, 0],
[1, 1, 1, ..., 0, 0, 0],
...,
[1, 1, 1, ..., 1, 0, 0],
[1, 1, 1, ..., 1, 1, 0],
[1, 1, 1, ..., 1, 1, 1]])
位置中的项目[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])
位置的项目[i]
告诉你是否k[i]
小于或等于它之前的所有项目。查找该数组为零的位置:
>>> np.where(np.cumprod(k <= k[:, None],
... axis=1)[np.diag_indices(k.shape[0])] == 0)
(array([5129, 5130, 5131, ..., 6324, 6325, 6326]),)
并且您将拥有满足您所需条件的所有值的索引。
如果您只对第一个感兴趣:
>>> np.argmax(np.cumprod(k <= k[:, None],
... axis=1)[np.diag_indices(k.shape[0])] == 0)
5129
这不是一个轻量级的操作,但如果你有足够的内存来容纳所有的布尔数组,它不会让你等待太久:
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