确定numpy数组的总和,同时排除某些值

时间:2014-07-31 13:27:23

标签: python arrays numpy sum

我想确定二维numpy数组的总和。但是,我希望从此求和中排除具有特定值的元素。最有效的方法是什么?

例如,在这里我初始化一个2的numpy数组,并将其中的几个替换为2:

import numpy

data_set = numpy.ones((10, 10))

data_set[4][4] = 2
data_set[5][5] = 2
data_set[6][6] = 2

如何排除二维数组中的元素,同时排除所有2?请注意,对于10乘10的数组,正确的答案应该是97,因为我用值2替换了三个元素。

我知道我可以使用嵌套for循环执行此操作。例如:

elements = []
for idx_x in range(data_set.shape[0]):
  for idx_y in range(data_set.shape[1]):
    if data_set[idx_x][idx_y] != 2:
      elements.append(data_set[idx_x][idx_y])

data_set_sum = numpy.sum(elements)

然而,根据我的实际数据(非常大),这太慢了。这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:5)

使用indexing with boolean arrays的numpy功能。在下面的示例中,data_set!=2计算为布尔数组,只要元素不是2(并且具有正确的形状),该数组为True。所以data_set[data_set!=2]是一种快速便捷的方法,可以获得一个不包含特定值的数组。当然,布尔表达式可能更复杂。

In [1]: import numpy as np
In [2]: data_set = np.ones((10, 10))
In [4]: data_set[4,4] = 2
In [5]: data_set[5,5] = 2
In [6]: data_set[6,6] = 2
In [7]: data_set[data_set != 2].sum()
Out[7]: 97.0
In [8]: data_set != 2
Out[8]: 
array([[ True,  True,  True,  True,  True,  True,  True,  True,  True,
         True],
       [ True,  True,  True,  True,  True,  True,  True,  True,  True,
         True],
       ...
       [ True,  True,  True,  True,  True,  True,  True,  True,  True,
         True]], dtype=bool)

答案 1 :(得分:3)

没有numpy,解决方案并不复杂:

x = [1,2,3,4,5,6,7]
sum(y for y in x if y != 7)
# 21

也适用于排除值列表:

# set is faster for resolving `in`
exl = set([1,2,3])
sum(y for y in x if y not in exl)
# 22

答案 2 :(得分:0)

这种方式如何利用numpy的布尔功能。

在获取总和之前,我们只需将符合规范的所有值设置为零,这样我们就不会像在数组中过滤它们那样改变数组的形状。

这样做的另一个好处是,它意味着我们可以在应用滤镜后沿轴进行求和。

import numpy

data_set = numpy.ones((10, 10))

data_set[4][4] = 2
data_set[5][5] = 2
data_set[6][6] = 2

print "Sum", data_set.sum()

another_set = numpy.array(data_set) # Take a copy, we'll need that later

data_set[data_set == 2] = 0  # Set all the values that are 2 to zero
print "Filtered sum", data_set.sum()
print "Along axis", data_set.sum(0), data_set.sum(1)

同样,我们可以使用任何其他布尔来设置我们希望从总和中排除的数据。

another_set[(another_set > 1) & (another_set < 3)] = 0
print "Another filtered sum", another_set.sum()