仅对python数组中的连续值求和

时间:2015-09-24 20:46:32

标签: python arrays numpy

我是python的新手(甚至编程!),所以我会尽可能清楚地解释我的问题。对你们来说这很容易,但我还没有找到令人满意的结果。

问题在于:

我有一个包含负值和正值的数组,比如说:

x = numpy.array([1, 4, 2, 3, -1, -6, -6, 5, 6, 7, 3, 1, -5, 4, 9, -5, -2, -1, -4])

我想仅总结连续,即仅( - 1,-6,-6) ,( - 5,-2,-1,-4)等。我已经尝试使用 numpy.where ,以及基于条件的 numpy.split

例如:

 for i in range(len(x)):
     if x[i] < 0.:
         y[i] = sum(x[i])

然而,正如您所料,我只是得到了数组中所有负值的总和。在这种情况下 sum ( - 1,-6,-6,-5,-5,-2,-1,-4) 人们可以与我分享一种美学和有效的方法来解决这个问题吗?我将对此表示感谢。

非常感谢

3 个答案:

答案 0 :(得分:7)

您可以使用itertools模块,此处使用groupby您可以根据这些符号对项目进行分组,然后检查它是否符合key函数中的条件,因此它包含负数然后产生总和,然后产生它,最后你可以使用chain.from_iterable函数来链接结果:

>>> from itertools import groupby,tee,chain
>>> def summ_neg(li):
...     for k,g in groupby(li,key=lambda i:i<0) :
...           if k:
...              yield [sum(g)]
...           yield g
... 
>>> list(chain.from_iterable(summ_neg(x)))
[1, 4, 2, 3, -13, 5, 6, 7, 3, 1, -5, 4, 9, -12]

或者作为更加pythonic的方式使用列表理解:

 list(chain.from_iterable([[sum(g)] if k else list(g) for k,g in groupby(x,key=lambda i:i<0)]))
[1, 4, 2, 3, -13, 5, 6, 7, 3, 1, -5, 4, 9, -12]

答案 1 :(得分:1)

这是一个矢量化的NumPythonic解决方案 -

# Mask of negative numbers
mask = x<0

# Differentiation between Consecutive mask elements. We would look for 
# 1s and -1s to detect rising and falling edges in the mask corresponding 
# to the islands of negative numbers.
diffs = np.diff(mask.astype(int))

# Mask with 1s at start of negative islands
start_mask = np.append(True,diffs==1) 

# Mask of negative numbers with islands of one isolated negative numbers removed
mask1 = mask & ~(start_mask & np.append(diffs==-1,True))

# ID array for IDing islands of negative numbers
id = (start_mask & mask1).cumsum()

# Finally use bincount to sum elements within their own IDs
out = np.bincount(id[mask1]-1,x[mask1])

您也可以使用np.convolve获取mask1,就像这样 -

mask1 = np.convolve(mask.astype(int),np.ones(3),'same')>1

您还可以在每个&#34;岛&#34;中获得负数的计数。对现有代码进行一些调整 -

counts = np.bincount(id[mask1]-1)

示例运行 -

In [395]: x
Out[395]: 
array([ 1,  4,  2,  3, -1, -6, -6,  5,  6,  7,  3,  1, -5,  4,  9, -5, -2,
       -1, -4])

In [396]: out
Out[396]: array([-13., -12.])

In [397]: counts
Out[397]: array([3, 4])

答案 2 :(得分:1)

你可以标记负值....并使用普通python执行此操作

prev = False

    for i,v in enumerate(a):
            j = i + 1     
            if j < len(a):
                if a[i] < 0 and  a[j] < 0:
                    temp.append(v)
                    prev = True
                elif a[i] < 0 and prev:
                    temp.append(v)
                    prev = True
                elif a[i] > 0:
                    prev = False
            else:
                if prev and v < 0:
                    temp.append(v)

<强>输出

打印(温度)

[ - 1,-6,-6,-5,-2,-1,-4]

使用intertools我会这样做

def sum_conseq_negative(li):
    neglistAll = []
    for k, g in groupby(li, key=lambda i:i<0):
        negList = list(g)
        if k and len(negList) > 1:
            neglistAll.extend(negList)
    return sum(negList), len(negList)

 sumOf, numOf = sum_conseq_negative(li)

print("sum of negatives {} number of summed {}".format(sumOf,numOf))

负数之和-25总数7