Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多维数组-计算非零条目的最有效方法_Python_Arrays_Multidimensional Array - Fatal编程技术网

Python多维数组-计算非零条目的最有效方法

Python多维数组-计算非零条目的最有效方法,python,arrays,multidimensional-array,Python,Arrays,Multidimensional Array,嗨,在一个周六有趣的夜晚 我正在使用python,我非常喜欢它 假设我有一个python数组: x = [1, 0, 0, 1, 3] 计算列表中所有非零元素的最快方法是什么(ans:3)?另外,如果可能的话,我想对循环使用而不使用——最简洁的方式,在概念上说 [counter += 1 for y in x if y > 0] 现在-我真正的问题是我有一个多维数组,我真正想要避免的是执行以下操作: for p in range(BINS): for q in range(BI

嗨,在一个周六有趣的夜晚

我正在使用python,我非常喜欢它

假设我有一个python数组:

x = [1, 0, 0, 1, 3]
计算列表中所有非零元素的最快方法是什么(ans:3)?另外,如果可能的话,我想对循环使用而不使用——最简洁的方式,在概念上说

[counter += 1 for y in x if y > 0]
现在-我真正的问题是我有一个多维数组,我真正想要避免的是执行以下操作:

for p in range(BINS):
    for q in range(BINS):
        for r in range(BINS):
            if (mat3D[p][q][r] > 0): some_feature_set_count += 1
len([x for x in my_list if x != 0])
从我所看到的小python来看,我的直觉是有一种非常干净的语法(和有效的)方法来实现这一点


有人有想法吗?

对于一维情况:

sum(1 for i in x if i)
对于多维情况,可以嵌套:

sum(sum(1 for i in row if i) for row in rows)
或者在一个构造中完成所有操作:

sum(1 for row in rows
      for i in row if i)

虽然可能不简洁,但我选择如何解决这一问题,它适用于任何维度:

def sum(li):
  s = 0
  for l in li:
    if isinstance(l, list):
      s += sum(l)
    elif l:
      s += 1
  return s
不能确定它是否是最快的方法,但它是递归的,并且适用于N维列表

zeros([1,2,3,4,0,[1,2,3,0,[1,2,3,0,0,0]]]) => 10

如果您使用的是Python中的多维数组,那么下面的内容与@Marcelo的答案类似,但有点简洁:

>>> a = numpy.array([[1,2,3,0],[0,4,2,0]])
>>> sum(1 for i in a.flat if i)
5
>>>

我会稍微改变Marcelo对以下问题的回答:

for p in range(BINS):
    for q in range(BINS):
        for r in range(BINS):
            if (mat3D[p][q][r] > 0): some_feature_set_count += 1
len([x for x in my_list if x != 0])

上面的sum()欺骗了我一秒钟,因为我以为他得到的是总值而不是计数,直到我看到1在开始处徘徊。我宁愿使用len()来明确说明问题。

如果使用numpy,并且您的3D数组是一个numpy数组,那么这一行程序将实现以下功能:

numpy.where(your_array_name != 0, 1, 0).sum()
例如:

In [23]: import numpy

In [24]: a = numpy.array([ [[0, 1, 2], [0, 0, 7], [9, 2, 0]], [[0, 0, 0], [1, 4, 6], [9, 0, 3]], [[1, 3, 2], [3, 4, 0], [1, 7, 9]] ])

In [25]: numpy.where(a != 0, 1, 0).sum()
Out[25]: 18

使用链减少阵列查找:

from itertools import chain
BINS = [[[2,2,2],[0,0,0],[1,2,0]],
        [[1,0,0],[0,0,2],[1,2,0]],
        [[0,0,0],[1,1,1],[1,3,0]]]
sum(1 for c in chain.from_iterable(chain.from_iterable(BINS)) if c > 0)
14
我还没有做任何性能检查。但它不使用任何重要的内存。
请注意,它使用的是生成器表达式,而不是列表。添加[列表理解]语法将创建一个要求和的数组,而不是一次输入一个数字求和。

+1用于控制语法@原始海报:至于效率,你的代码是你能得到的最有效的。它具有任务所需的最小空间和时间复杂性(如果您使用的是Python<3.0,请使用
xrange
而不是
range
),而且,我个人觉得您的代码虽然更长、更少pythonnesque,但比任何语法技巧都清晰得多是
和(bool(i)表示x中的i)
。。但是它对于使用其他谓词(如
i>0
@Santiago)计数更有用。您应该对这两个选项计时。这可能会冒烟OP的代码。@THC4k:它会起作用,但效率不高(特别是对于稀疏矩阵),因为它必须为每个元素生成一个值。@Santiago:回到主题上来,列表理解是惯用的Python,我想从第一天起就应该教用户如何使用它们,因为它们会产生更干净的结果,而且通常是更高效的代码。我总是尽可能早地教人们这方面的东西,我发现,尽管他们必须经历短暂的心理调整,但在这个过程中,他们总是成为更好的程序员,用更少的努力生成更好的代码。这需要O(N)空间,这对于大型数组来说并不理想,而且它的Python语法无效。我想你的意思是
x!=0
。使用
sum
计算元素非常惯用。您应该习惯它,这样您就不必像在这里一样构建列表来扔掉它们。另外,我想你的意思是
x不是0
,它应该是
x!=0
这本身应该是
x
两个公平点,谢谢你的提醒。改变了条件,但留下了透镜,以便其他人可以看到什么不可以做。列表理解是否正确?我可能忘了那一点。你真的不应该给总和加阴影。它是一个内置的。如果你有numpy,你可以只写
np.sum(a)
(假设传统的
导入numpy为np
)。