根据值拆分Numpy数组

时间:2016-07-09 00:47:54

标签: python numpy

假设我有这个NumPy数组:

a = np.array([0, 3, 5, 5, 0, 10, 14, 15, 56, 0, 12, 23, 45, 23, 12, 45, 
              0, 1, 0, 2, 3, 4, 0, 0 ,0])

我想在0之间打印所有数字并自动将它们添加到新的np.array(见下文):

a1=[3, 5, 5]
a2=[10, 14, 15, 56]
a3=[12, 23, 45, 23, 12, 45]
a4=[1]
a5=[2, 3, 4]

是否有内置功能来执行此操作?

6 个答案:

答案 0 :(得分:6)

您可以使用groupby()中的itertools函数,并将key指定为零或非零的布尔条件。以这种方式,所有连续的零和非零将被组合在一起。使用if过滤器获取非零组,并使用list将非零石斑鱼转换为列表。

from itertools import groupby
[list(g) for k, g in groupby(a, lambda x: x != 0) if k]

# [[3, 5], [10, 14, 15, 56], [12, 23, 45, 23, 12, 45], [1], [2, 3, 4]]

答案 1 :(得分:3)

您可以使用np.where:

获取零的索引
zeros = np.where(a == 0)[0]

迭代每一对以切割数组:

[a[i+1:j] for i, j in zip(zeros, zeros[1:]) if len(a[i+1:j])>0]

Out[46]: 
[array([3, 5]),
 array([10, 14, 15, 56]),
 array([12, 23, 45, 23, 12, 45]),
 array([1]),
 array([2, 3, 4])]

答案 2 :(得分:3)

NumPy的split()where()列表标识:

[x[x!=0] for x in np.split(a, np.where(a==0)[0]) if len(x[x!=0])]

[array([3, 5, 5]),
 array([10, 14, 15, 56]),
 array([12, 23, 45, 23, 12, 45]),
 array([1]),
 array([2, 3, 4])]

答案 3 :(得分:2)

以下是使用np.wherenp.split -

的矢量化方法
idx = np.where(a!=0)[0]
aout = np.split(a[idx],np.where(np.diff(idx)!=1)[0]+1)

示例运行 -

In [23]: a
Out[23]: 
array([ 0,  3,  5,  5,  0, 10, 14, 15, 56,  0,  0,  0, 12, 23, 45, 23, 12,
       45,  0,  1,  0,  2,  3,  4,  0,  0,  0])

In [24]: idx = np.where(a!=0)[0]

In [25]: np.split(a[idx],np.where(np.diff(idx)!=1)[0]+1)
Out[25]: 
[array([3, 5, 5]),
 array([10, 14, 15, 56]),
 array([12, 23, 45, 23, 12, 45]),
 array([1]),
 array([2, 3, 4])]

答案 4 :(得分:0)

不需要numpy,这个lambda函数在列表上工作,但是我们可以在进出的方式上将你的numpy数组转换成列表和从列表中转换出来:

cut = lambda x: [j for j in [cut(x[:x.index(0)])]+cut(x[x.index(0)+1:]) if j] if x.count(0) else x

numpy.array(cut(list(a)))

# array([[3, 5, 5], [10, 14, 15, 56], [12, 23, 45, 23, 12, 45], [1], [2, 3, 4]], dtype=object)

答案 5 :(得分:0)

这可能是最糟糕的方法,但是您也可以将数组转换为字符串,然后将该字符串拆分几次:

long_string = "_".join(a.astype(str))

while long_string.startswith("0_"):
    long_string = long_string.removeprefix("0_")
while long_string.endswith("_0"):
    long_string = long_string.removesuffix("_0")

result = [list(map(int, i.split("_"))) for i in long_string.split("_0_")]

# result: [[3, 5, 5], [10, 14, 15, 56], [12, 23, 45, 23, 12, 45], [1], [2, 3, 4]]

.removeprefix().removesuffix()需要Python 3.9。