[英]What is the pythonic way of slicing an array into stepped contiguous blocks?
假設我有一個數組/列表/字符串,例如arr=[0,1,2,3,...,97,98,99]
如何對其進行切片以使輸出是連續的塊,步長為一定量,例如:
out = [0,1,10,11,20,21..]
我在out = arr[(0,1)::10]
上嘗試了變種,但無濟於事。 我錯過了一些非常簡單的事嗎?
首先:您對哪種類型感興趣? numpy
數組允許擴展索引,而python內置函數(即list
, tuple
, str
等)則不允許。
如果您想要一個適用於任何一維序列的解決方案,那么只需使用:
from itertools import chain
result = list(chain.from_iterable(seq[i:i+step] for i in range(0, len(seq), step2))
在你的情況,你想step
是2
和step2
是10
。
在任何情況下,對於通用序列,您必須為要選擇的每個連續部分執行一個切片,因此我認為您不能做得比這更好。
對於numpy
數組,您可以將數組reshape
整形為多維數組,以便連續部分都位於行的開頭並選擇行的第一部分:
In [1]: import numpy as np
In [2]: seq = np.array(range(100))
In [3]: seq2 = seq.reshape((10, 10))
In [4]: seq2[:, :2]
Out[4]:
array([[ 0, 1],
[10, 11],
[20, 21],
[30, 31],
[40, 41],
[50, 51],
[60, 61],
[70, 71],
[80, 81],
[90, 91]])
In [5]: seq2[:, :2].reshape((2*10,))
Out[5]:
array([ 0, 1, 10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80,
81, 90, 91])
(有很多方法可以重塑和平整結果;如果您有興趣,請閱讀numpy
文檔)。
但請注意,如果切片重疊,這將失敗,而第一個解決方案有效(重復一些元素,但這應該發生)。
如果你不關心重疊切片(即切片永遠不會重疊),那么你可以簡單地做:
indices = frozenset(range(step))
result = [el for i, el in enumerate(seq) if i % step2 in indices]
這似乎比進行多次切片更有效,但我不會那么肯定,因為在這里你需要每個元素的索引操作而不是每個切片一個。 特別是在CPython中,這可能不比第一個解決方案更有效,特別是如果step
很大。
從最后一個想法,你也可以做一些事情,以避免reshape
numpy數組:
indices = frozenset(range(step))
arr = np.array(i % step2 in indices for i in range(len(seq)))
result = seq[arr]
但是我想不出一種簡單有效的構建arr
數組的方法,所以我懷疑它是否能提高性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.