Skip to main content
 首页 » 编程设计

Python之根据数组值将数组拆分为多个数组

2025年05月04日13davidwang456

我有一个列表需要分成多个不同大小的列表。原始列表中的值随机增加大小,直到 split 点,在继续增加之前值下降。值在拆分后必须保持顺序。

例如 原始列表

[100, 564, 572, 578, 584, 590, 596, 602, 608, 614, 620, 625, 631, 70, 119,  
125, 130, 134, 139, 144, 149, 154, 159, 614, 669, 100, 136, 144, 149, 153,  
158, 163, 167, 173, 179, 62, 72, 78, 82, 87, 92, 97, 100, 107, 112, 117,  
124, 426, 100, 129, 135, 140, 145, 151] 

拆分后:

[100, 564, 572, 578, 584, 590, 596, 602, 608, 614, 620, 625, 631] 
[70, 119, 125, 130, 134, 139, 144, 149, 154, 159, 614, 669] 
[100, 136, 144, 149, 153, 158, 163, 167, 173, 179] 
[62, 72, 78, 82, 87, 92, 97, 100, 107, 112, 117, 124, 426] 
[100, 129, 135, 140, 145, 151] 

我已经搜索了一个解决方案,发现 numpy.where 和 numpy.diff 可能是候选者,但我不确定如何实现。

感谢您的帮助!

请您参考如下方法:

方法 #1

使用 NumPy 的 numpy.split 将数组列表作为输出 -

import numpy as np 
 
arr = np.array(a) # a is input list 
out = np.split(arr,np.flatnonzero(arr[1:] < arr[:-1])+1) 

方法 #2

使用循环理解直接拆分列表,从而避免 numpy.split 以提高效率 -

idx = np.r_[0, np.flatnonzero(np.diff(a)<0)+1, len(a)] 
out = [a[idx[i]:idx[i+1]] for i in range(len(idx)-1)] 

给定样本的输出-

In [52]: idx = np.r_[0, np.flatnonzero(np.diff(a)<0)+1, len(a)] 
 
In [53]: [a[idx[i]:idx[i+1]] for i in range(len(idx)-1)] 
Out[53]:  
[[100, 564, 572, 578, 584, 590, 596, 602, 608, 614, 620, 625, 631], 
 [70, 119, 125, 130, 134, 139, 144, 149, 154, 159, 614, 669], 
 [100, 136, 144, 149, 153, 158, 163, 167, 173, 179], 
 [62, 72, 78, 82, 87, 92, 97, 100, 107, 112, 117, 124, 426], 
 [100, 129, 135, 140, 145, 151]] 

我们在这里使用 np.diff,在这种情况下它会输入一个列表,然后计算微分。因此,更好的替代方法是转换为数组,然后使用它的移位切片之间的比较,而不是实际计算微分值。因此,我们也可以像这样得到 idx -

arr = np.asarray(a) 
idx = np.r_[0, np.flatnonzero(arr[1:] < arr[:-1])+1, len(arr)] 

让我们计时,看看是否有任何改进 -

In [84]: a = np.random.randint(0,100,(1000,100)).cumsum(1).ravel().tolist() 
 
In [85]: %timeit np.r_[0, np.flatnonzero(np.diff(a)<0)+1, len(a)] 
100 loops, best of 3: 3.24 ms per loop 
 
In [86]: arr = np.asarray(a) 
 
In [87]: %timeit np.asarray(a) 
100 loops, best of 3: 3.05 ms per loop 
 
In [88]: %timeit np.r_[0, np.flatnonzero(arr[1:] < arr[:-1])+1, len(arr)] 
10000 loops, best of 3: 77 µs per loop 
 
In [89]: 3.05+0.077 
Out[89]: 3.127 

因此,转换和比较方法的边际改进:np.asarray(a) 消耗 大部分运行时间。