根据索引切割numpy数组

时间:2018-05-01 16:20:15

标签: python arrays numpy optimization

我有1D numpy数组。此数组中两个后续值之间的差异是一个或大于一。我想将数组切割成每个出现差异大于1的部分。因此:

arr = numpy.array([77, 78, 79, 80, 90, 91, 92, 100, 101, 102, 103, 104])

应该成为

[array([77, 78, 79, 80]), array([90, 91, 92]), array([100, 101, 102, 103, 104])]

我有以下代码可以解决问题,但我感觉我要在这里复杂化。必须有更好/更pythonic的方式。任何人都有更优雅的方法吗?

import numpy

def split(arr, cut_idxs):

  empty_arr = []
  for idx in range(-1, cut_idxs.shape[0]):  
    if idx == -1:
      l, r = 0, cut_idxs[0]
    elif (idx != -1) and (idx != cut_idxs.shape[0] - 1):
      l, r = cut_idxs[idx] + 1, cut_idxs[idx + 1]
    elif idx == cut_idxs.shape[0] - 1:
      l, r = cut_idxs[-1] + 1, arr.shape[0]

    empty_arr.append(arr[l:r + 1]) 

  return empty_arr 


arr = numpy.array([77, 78, 79, 80, 90, 91, 92, 100, 101, 102, 103, 104])
cuts = numpy.where(numpy.ediff1d(arr) > 2)[0]

print split(arr, cuts)

2 个答案:

答案 0 :(得分:2)

一种Pythonic方式是 -

airflow webserver

示例运行 -

np.split(arr, np.flatnonzero(np.diff(arr)>1)+1)

另一位In [10]: arr Out[10]: array([ 77, 78, 79, 80, 90, 91, 92, 100, 101, 102, 103, 104]) In [11]: np.split(arr, np.flatnonzero(np.diff(arr)>1)+1) Out[11]: [array([77, 78, 79, 80]), array([90, 91, 92]), array([100, 101, 102, 103, 104])] -

slicing

答案 1 :(得分:0)

切片的另一种方法是,使用np.diff获取适当的索引:

import numpy as np
def split(arr):
    idx = np.pad(np.where(np.diff(arr) > 1)[0]+1, (1,1),
             'constant', constant_values = (0, len(arr)))
    return [arr[idx[i]: idx[i+1]] for i in range(len(idx)-1)]

结果:

arr = np.array([77, 78, 79, 80, 90, 91, 92, 100, 101, 102, 103, 104])
>>> split(arr)
[array([77, 78, 79, 80]), array([90, 91, 92]), array([100, 101, 102, 103, 104])]

在您的情况下,您的切片“地图”idx最终为:array([ 0, 4, 7, 12]),这是diff大于1的地方(索引4和{{ 1}}),使用np.pad

在左侧用零填充,在右侧填充数组的长度(7

12,正如@Divakar所建议的那样