反向顺序数字

5 python numpy

我有一个非常长的数组,我试图以尽可能高效的方式执行以下操作:

对于列表中每个连续递增的块,我必须反转它的顺序.

因此,对于以下数组:

a = np.array([1,5,7,3,2,5,4,45,1,5,10,12])
Run Code Online (Sandbox Code Playgroud)

我想获得:

array([7,5,1,3,5,2,45,4,12,10,5,1])
Run Code Online (Sandbox Code Playgroud)

我想知道这是否可以被矢量化,numpy或许使用?

我已经有一些答案,这个前面的问题,但结果,他们虽然是很大的进步,但仍然有点慢.

iGi*_*ian 2

其他没有依赖项的选项:

array = [1,5,7,3,2,5,4,45,1,5,10,12]

res, memo = [], []
for e in array:
  if len(memo) == 0 or e > memo[-1]: memo.append(e)
  else:
    res.extend(reversed(memo))
    memo = [e]
res.extend(reversed(memo))

res # => [7, 5, 1, 3, 5, 2, 45, 4, 12, 10, 5, 1]
Run Code Online (Sandbox Code Playgroud)


修改后的版本更快一点:

def reverse_if_chunck_increases(array):
  res, memo, last_memo = [], [], None
  for e in array:
    if not last_memo or e > last_memo:
      last_memo = e
      memo.append(e)
    else:
      res.extend(memo[::-1])
      last_memo, memo = e, [e]
  res.extend(memo[::-1])
  return res

print(reverse_if_chunck_increases(array) == [7, 5, 1, 3, 5, 2, 45, 4, 12, 10, 5, 1])
#=> True
Run Code Online (Sandbox Code Playgroud)


答案被接受后编辑(也许有用。)

我能够如此轻松地获得结果,并且在 Ruby 中编码速度明显更快:

array = [1,5,7,3,2,5,4,45,1,5,10,12]

res, memo = [], []
for e in array:
  if len(memo) == 0 or e > memo[-1]: memo.append(e)
  else:
    res.extend(reversed(memo))
    memo = [e]
res.extend(reversed(memo))

res # => [7, 5, 1, 3, 5, 2, 45, 4, 12, 10, 5, 1]
Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么没有itertool喜欢chunk_while。然后我尝试使用以下代码编写类似的代码yield

def reverse_if_chunk_increases(array):
  i, x, size, res = 0, 0, len(array), []
  while i < size-1:
    if array[i] > array[i+1]:
      yield array[x:i+1][::-1]
      x = i +1
    i += 1
  yield array[x:size][::-1]
Run Code Online (Sandbox Code Playgroud)

执行速度非常快,但它返回一个生成器来迭代而不是一个列表:

chunks = reverse_if_chunk_increases(array)
for chunk in chunks:
  print(chunk)
# [7, 5, 1]
# [3]
# [5, 2]
# [45, 4]
# [12, 10, 5, 1]
Run Code Online (Sandbox Code Playgroud)

可以将其转换为列表,这是最慢的过程。请注意,生成器只能被调用一次。删除后[::-1]您会得到类似于 Ruby enumerator/generator 的结果chunk_while