at.*_*at. 8 python list dataframe python-3.x pandas
有没有一种有效或优雅的方法来检索Python中列表的所有k大小子列表?例如:
arr = [2, 3, 5, 7, 11, 13]
Run Code Online (Sandbox Code Playgroud)
我想要所有 3 元素子列表:
result = [[2, 3, 5],
[3, 5, 7],
[5, 7, 11],
[7, 11, 13]]
Run Code Online (Sandbox Code Playgroud)
我知道我可以用 for 循环创建这个,用 切片列表arr[i:i+3],但我正在处理的列表是巨大的,我希望有一个有效的机制,或者至少是一个优雅的或 Pythonic 的机制。
我也在使用 Pandas,很高兴使用 Pandas 机制。
如果您确实想构建列表,我认为您不会比像这样的基本列表理解做得更好:
arr = [2, 3, 5, 7, 11, 13]
result = [arr[i:i+k] for i in range(len(arr)-k+1)]
Run Code Online (Sandbox Code Playgroud)
如果你想最小化内存使用,你可以使用生成器:
arr = [2, 3, 5, 7, 11, 13]
def window(arr, k):
for i in range(len(arr)-k+1):
yield arr[i:i+k]
for group in window(arr, 3):
... # do something with group
Run Code Online (Sandbox Code Playgroud)
您还可以做一些事情,将列表的副本zip放在一起,每个副本偏移一。k但这将占用与第一个解决方案一样多的内存,并且可能没有太多性能优势。
numpy 或 pandas 中可能有一些快速有效的东西,但您需要更多地展示您的输入和输出应该是什么样子。
这里还有一些其他的想法,但它们专注于一般的迭代(您只能将项目取出一次),而不是列表(您可以通过索引访问项目,可能会重复访问)。
您可以使用more_itertools
import more_itertools
list(more_itertools.windowed(arr,3))
Run Code Online (Sandbox Code Playgroud)
[(2, 3, 5), (3, 5, 7), (5, 7, 11), (7, 11, 13)]
Run Code Online (Sandbox Code Playgroud)
或者
使用itertools:
from itertools import islice
def pairwise(iterable, n):
"s -> (s0,s1,..s(n-1)), (s1,s2,.., sn), (s2, s3,..,s(n+1)), ..."
iters = iter(iterable)
result = tuple(islice(iters, n))
if len(result) == n:
yield result
for elem in iters:
result = result[1:] + (elem,)
yield result
Run Code Online (Sandbox Code Playgroud)
您可以使用步幅:
arr = [2, 3, 5, 7, 11, 13]
def rolling_window(a, window):
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
a = rolling_window(np.array(arr), 3)
print (a)
[[ 2 3 5]
[ 3 5 7]
[ 5 7 11]
[ 7 11 13]]
print (a.tolist())
[[2, 3, 5],
[3, 5, 7],
[5, 7, 11],
[7, 11, 13]]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5342 次 |
| 最近记录: |