【问题标题】:Slice Array Given Range from another array in Python从 Python 中的另一个数组切分给定范围的数组
【发布时间】:2012-05-29 21:05:41
【问题描述】:

为了更清楚,让我改写我最初在下面提出的问题。

我有一系列数据点,当有人迈出一步然后又迈出一步时,这些数据点的幅度会上升和下降。零是脚离开地面的时候。

一个简单的例子如下所示:

 data_array = (0,0,0,10,20,50,40,30,10,0,0,0,0,0,10,20,50,40,30,10,0,0)

我通过在一个数组中记录开始(所有开始的索引)和在另一个数组中记录来确定每个步骤何时开始和停止。

开始 = (4 15)

停止 = (9 20)

问题:现在,我想从初始数组中切出每个步骤的实际数据,并将它们分成列。

[注意:如果有必要,我们知道开始或停止数组中的数据量所采取的步数。]

10 10

20 20

50 50

40 40

30 30

10 10

我不知道如何使用这些开始和停止索引来分割初始数组。或者,我没有找到过滤功能来分割步骤。

顺便说一句(第二次编辑) 如果有帮助,这是我正在使用的一些代码:

sigma = 5

threshold = 30

above_threshold = gaussian_filter(Fz, sigma=sigma) > threshold

#---INDEX ALL STATE CHANGES---

ind = np.where(np.diff(above_threshold))[0] + 1

print ind

原始问题

在这种类型的数组中:

data_array = (0,0,0,10,20,50,40,30,10,0,0)

我确定值何时高于 20 和低于 20。我通过以下操作将这些索引返回为开始(高于 20)和停止(低于 20):

startstop = np.vstack((ind[::2], ind[1::2])).T   
starts1=np.vstack((ind[::2])).T
stops1=np.vstack((ind[1::2])).T

有人可以使用 numpy(或不使用)为我指出正确的方向,以便我可以使用这些数组之一(startstop、starts1、stops1)提取 data_array 中的所有这些值来获得:

new_array = (50,40,30)

谢谢, 斯科特

【问题讨论】:

    标签: python arrays numpy slice


    【解决方案1】:

    Python 列表是用方括号定义的,我们想要生成一个列表列表(其中每一部分都包含您定义的段之一)。由于计算机从 0 开始计数,因此您的“第 4 个元素是开始”转换为数组索引 = 3。

    一个怪癖是,要查询第 4 到第 9 个元素,我们将使用 data_array[3:9]:此切片表示法为您提供从指定的第一个元素开始的每个元素,直到(但不包括)最后一个元素。其余的是一个列表推导,可以遍历任意数量的步骤段。

    starts = [4, 15]
    stops = [9, 20]
    data_array = [0,0,0,10,20,50,40,30,10,0,0,0,0,0,10,20,50,40,30,10,0,0]
    segments = [ data_array[starts[i] - 1: stops[i]  ]  for i in range( len(starts) ) ]
    

    返回

    >>> segments
    [[10, 20, 50, 40, 30, 10], [10, 20, 50, 40, 30, 10]]
    

    每组步骤(段)都可以单独访问:

    >>>segments[0]
    [10, 20, 50, 40, 30, 10]
    

    编辑:或者...如果您需要使用 numpy 数组,请尝试: 段 = array([ data_array[starts[i] - 1:stops[i] ] for i in range(len(starts) ) ])

    我尝试在其他模块中工作以直接获取数组(使用itertools.isliceitertools.chainnumpy.fromiter 等)。但即使更高级的解决方案有效,我不确定它是否会比转换为数组提供显着的速度优势,而且它会不那么简洁。见:How do I build a numpy array from a generator?

    【讨论】:

    • 如果我将我的 numpy 数组扁平化为一维列表,这将有效。但是,然后我将不得不重建新的 numpy 数组以利用数学函数在每个段上运行。有什么建议吗?
    • 根据数据的大小,您可能可以在最后将其转换为数组:segments = array [ list comprehension ])。或者,您可以花点心思并结合其他功能/模块。我将编辑我的帖子以包含使用 numpy 的替代解决方案。
    【解决方案2】:

    我不明白你的做法,但你能用filter吗?:

    >>> data_array = (0,0,0,10,20,50,40,30,10,0)
    >>> filter(lambda x: x>20,data_array)
    
    (50, 40, 30)
    

    也适用于 numpy 数组。

    【讨论】:

    • 过滤器现在很有吸引力。我目前正在使用 sigma = 5 threshold = 30 above_threshold = gaussian_filter(Fz, sigma=sigma) > threshold #array with True/Falso pending values above/below filter #---INDEX ALL STATE CHANGES--- ind = np.where (np.diff(above_threshold))[0] + 1 print ind
    • 抱歉,stackoverflow 的新手,不知道如何更好地格式化我的回复。希望这是有道理的。
    【解决方案3】:

    take() 会做你想做的事,我想。

    data_array = np.array([0,0,0,10,20,50,40,30,10,0])
    
    
    b = data_array.take([1,2,3])
    print b
    

    输出:

    [ 0  0 10]
    

    阅读更多:take() more on take

    【讨论】:

    • 谢谢,以后可能会派上用场。但是,我需要自动化这个,而不是输入 1,2,3。
    • 可以替换数组[1,2,3]。使用您制作的具有所需元素索引的数组。就像这样: b = data_array.take(starts1) 。你以为这是你的问题吗?
    • starts1 仅包含起始索引(一个元素),我在 stop1 中有范围的结尾。我可以用每次开始和停止之间的所有索引创建一个新数组。然后把它们传进去。不过看起来很贵?
    【解决方案4】:

    你的问题不是很清楚,但如果你问的是如何对 Python 列表或可迭代对象进行切片,请使用内置的slice function

    >>> data_array = (0,0,0,10,20,50,40,30,10,0)
    >>> data_array[slice(5,8)]
    (50, 40, 30)
    >>> new_list=list(data_array[slice(5,8)])
    >>> new_list
    [50, 40, 30]
    

    【讨论】:

    • 我在上面改写了我的问题。你是对的,不是很清楚。我可以在不输入 5、8 的情况下使用您的建议吗?我之前尝试过,但无法传入变量来自动执行代码并取出多个切片。
    • @Scott:嗯,是的。你可以做data_array[slice(start,stop)],内置的切片比l[8:10]的切片语法更不挑剔。
    • 有道理,谢谢。似乎我的主要问题是我真的试图将所有内容保存在最初拥有数据的 2D numpy 数组中。我将它展平成一个列表并工作。但是,我想重建 numpy 数组以在每个段上完成数学运算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多