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

Mat*_*_EJ 1 python arrays split numpy

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

例如原始列表

[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]
Run Code Online (Sandbox Code Playgroud)

拆分后:

[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]
Run Code Online (Sandbox Code Playgroud)

我已经找到了解决方案,找到numpy.where并且numpy.diff可能是候选人,但我不确定如何实施.

谢谢您的帮助!

Div*_*kar 6

方法#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)
Run Code Online (Sandbox Code Playgroud)

方法#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)]
Run Code Online (Sandbox Code Playgroud)

给定样本的输出 -

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]]
Run Code Online (Sandbox Code Playgroud)

我们在np.diff这里使用,在这种情况下以列表形式提供,然后计算差异.因此,更好的替代方案是转换为数组,然后使用它的移位切片之间的比较,而不是实际计算微分值.因此,我们也可以idx这样做 -

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

我们来看看它是否有任何进步 -

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
Run Code Online (Sandbox Code Playgroud)

因此,转换和比较方法与转换相比有一个微小的改进:np.asarray(a) 吃掉运行时的大部分时间.