简体   繁体   English

等于或大于 0 时对三个连续数求和 - Python

[英]Summing three consecutive number when equal to or great than 0 - Python

I am using numpy in Python我在 Python 中使用 numpy

I have an array of numbers, for example:我有一个数字数组,例如:

arr = np.array([0.1, 1, 1.2, 0.5, -0.3, -0.2, 0.1, 0.5, 1)

If i is a position in the array, I want to create a function which creates a running sum of i and the two previous numbers, but only accumulating the number if it is equal to or greater than 0.如果i是数组中的 position ,我想创建一个 function ,它创建i和前两个数字的运行总和,但只有当它等于或大于 0 时才累加该数字。

In other words, negative numbers in the array become equal to 0 when calculating the three number running sum.换句话说,数组中的负数在计算三数运行和时等于0。

For example, the answer I would be looking for here is例如,我要在这里寻找的答案是

2.3, 2.7, 1.7, 0.5, 0.1, 0.6, 1.6

The new array has two elements less than the original array as the calculation can't be completed for the first two number.新数组的元素比原始数组少两个,因为前两个数字的计算无法完成。

Thank you !谢谢 !

As Dani Mesejo answered, you can use stride tricks.正如 Dani Mesejo 回答的那样,您可以使用跨步技巧。 You can either use clip or boolean indexing to handle the <0 elements.您可以使用剪辑或 boolean 索引来处理 <0 元素。 I have explained how stride tricks work below -我在下面解释了步幅技巧的工作原理 -

  1. arr[arr<0]=0 sets all elements below 0 as 0 arr[arr<0]=0将所有低于 0 的元素设置为 0
  2. as_strided takes in the array, the expected shape of the view (7,3) and the number of strides in the respective axes, (8,8) . as_strided接受数组、视图的预期形状(7,3)和各个轴上的步幅数(8,8) This is the number of bytes you have to move in axis0 and axis1 respectively to access the next element.这是您必须分别在axis0axis1中移动以访问下一个元素的字节数。 Eg If you want to move every 2 elements, then you can set it to (16,8) .例如,如果您想移动每 2 个元素,那么您可以将其设置为(16,8) This means you would move 16 bytes each time to get the element in axis0 (which is 0.1->1.2->0->0.1->.. , till a shape of 7 ) and 8 bytes each time to get element in axis1 (which is 0.1->1->1.2 , till a shape of 3 )这意味着您每次将移动 16 个字节以获取 axis0 中的元素(即0.1->1.2->0->0.1->.. ,直到形状为7 ),每次移动 8 个字节以获取 axis1 中的元素(这是0.1->1->1.2 ,直到形状为3

Use this function with caution.请谨慎使用此 function。 Always use x.strides to define the strides parameter to avoid corrupting memory!始终使用 x.strides 来定义 strides 参数以避免损坏内存!

  1. Lastly, sum this array view over axis=1 to get your rolling sum.最后,在axis=1上对这个数组视图求和以获得滚动总和。
arr = np.array([0.1, 1, 1.2, 0.5, -0.3, -0.2, 0.1, 0.5, 1])
w = 3  #rolling window

arr[arr<0]=0

shape = arr.shape[0]-w+1, w  #Expected shape of view (7,3)
strides = arr.strides[0], arr.strides[0] #Strides (8,8) bytes
rolling = np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

rolling_sum = np.sum(rolling, axis=1)
rolling_sum
array([2.3, 2.7, 1.7, 0.5, 0.1, 0.6, 1.6])

You could clip , roll and sum :您可以剪辑滚动求和

import numpy as np


def rolling_window(a, window):
    """Recipe from https://stackoverflow.com/q/6811183/4001592"""
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)


a = np.array([0.1, 1, 1.2, 0.5, -0.3, -0.2, 0.1, 0.5, 1])

res = rolling_window(np.clip(a, 0, a.max()), 3).sum(axis=1)
print(res)

Output Output

[2.3 2.7 1.7 0.5 0.1 0.6 1.6]

You may use np.correlate to sweep an array of 3 ones over the clipped of arr to get desired output您可以使用np.correlatearr的剪辑上扫描 3 ones数组以获得所需的 output

In [20]: np.correlate(arr.clip(0), np.ones(3), mode='valid')
Out[20]: array([2.3, 2.7, 1.7, 0.5, 0.1, 0.6, 1.6])
arr = np.array([0.1, 1, 1.2, 0.5, -0.3, -0.2, 0.1, 0.5, 1])

def sum_3(x):
    collector = []
    
    for i in range(len(arr)-2):            
        collector.append(sum(arr[i:i+3][arr[i:i+3]>0]))
    return collector

#output

[2.3, 2.7, 1.7, 0.5, 0.1, 0.6, 1.6]

Easiest and most comprehensible way.最简单和最容易理解的方式。 The collector will append the sum of the 3 consecutive numbers if their indices are True otherwise, they are all turned to 0 s.收集器将 append 三个连续数字的总和,如果它们的索引是True否则,它们都变成0 s。

The method is not general, it is for 3 consecutives but you can adapt it.该方法不通用,连续3次,但您可以调整它。

def sum_any(x,n):
    collector = []
    for i in range(len(arr)-(n-1)):            
        collector.append(sum(arr[i:i+n][arr[i:i+n]>0]))
    return collector

Masked arrays and view_as_windows (which uses numpy strides under the hood) are built for this purpose:蒙面的 arrays 和 view_as_windows(在引擎盖下使用 numpy 跨步)是为此目的而构建的:

from skimage.util import view_as_windows
arr = view_as_windows(arr, 3)
arr2 = np.ma.masked_array(arr, arr<0).sum(-1)

output: output:

[2.3 2.7 1.7 0.5 0.1 0.6 1.6]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当第一个元素大于下一个元素时,减去列表中的连续元素-Python - Subtracting consecutive elements in a list when the first element is great than the next - Python Python - 运行平均值如果数字大于0 - Python - Running Average If number is great than 0 检查Python中连续相等元素的数量 - Check the number of consecutive equal elements in Python 查找列表中是否有三个连续的索引在python中不等于零 - Find if there are three consecutive indices in a list that ARE NOT equal to zero in python Python-总和大于或等于值的数字组合 - Python - Combination of Numbers Summing to Greater than or Equal to a Value Python程序找到等于n的连续数字值之和? - Python program find sum of consecutive number values equal to number n? 在Python中求和连续的第三个数字 - Summing consecutive third numbers in python 合并时间戳大于或等于的数据帧 - Merging data frames on timestamp great than or equal 检查 Python 列表是否有 X 个等于 Y 的连续值 - Check if a Python list has X number of consecutive values equal to Y 如何删除行:1)满足一定的标准和2)连续行的数量是多少? - How to drop rows that: 1)meet a certain criteria and 2) the number of consecutive rows are great?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM