我有一个非常长的数组,我试图以尽可能高效的方式执行以下操作:
对于列表中每个连续递增的块,我必须反转它的顺序.
因此,对于以下数组:
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或许使用?
我已经有一些答案,这个前面的问题,但结果,他们虽然是很大的进步,但仍然有点慢.
其他没有依赖项的选项:
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。
| 归档时间: |
|
| 查看次数: |
106 次 |
| 最近记录: |