我如何计算以下数组中的0和1的数量?

y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

y.count(0)为:

numpy。Ndarray对象没有属性计数


当前回答

您可以使用字典理解来创建简洁的一行代码。更多关于字典理解的内容可以在这里找到

>>> counts = {int(value): list(y).count(value) for value in set(y)}
>>> print(counts)
{0: 8, 1: 4}

这将创建一个字典,将ndarray中的值作为键,并将值的计数分别作为键的值。

当您想要计算该格式数组中某个值的出现次数时,这种方法就可以工作。

其他回答

使用numpy.unique:

import numpy
a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
unique, counts = numpy.unique(a, return_counts=True)

>>> dict(zip(unique, counts))
{0: 7, 1: 4, 2: 1, 3: 2, 4: 1}

使用collections.Counter的非numpy方法;

import collections, numpy
a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
counter = collections.Counter(a)

>>> counter
Counter({0: 7, 1: 4, 3: 2, 2: 1, 4: 1})
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

如果你知道它们是0和1

np.sum(y)

给出1的个数。Np.sum (1-y)给出0。

一般来说,如果你想计算0而不是0(但可能是2或3):

np.count_nonzero(y)

给出非零的个数。

但是如果您需要更复杂的东西,我不认为numpy将提供一个很好的计数选项。在这种情况下,转到集合:

import collections
collections.Counter(y)
> Counter({0: 8, 1: 4})

这就像字典一样

collections.Counter(y)[0]
> 8

将数组y转换为列表l,然后执行l.count(1)和l.count(0)

>>> y = numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>> l = list(y)
>>> l.count(1)
4
>>> l.count(0)
8 

您可以使用字典理解来创建简洁的一行代码。更多关于字典理解的内容可以在这里找到

>>> counts = {int(value): list(y).count(value) for value in set(y)}
>>> print(counts)
{0: 8, 1: 4}

这将创建一个字典,将ndarray中的值作为键,并将值的计数分别作为键的值。

当您想要计算该格式数组中某个值的出现次数时,这种方法就可以工作。

如果你对最快的执行感兴趣,你提前知道要查找哪个(s)值,并且你的数组是1D,或者你对扁平数组上的结果感兴趣(在这种情况下,函数的输入应该是np.ravel(arr)而不仅仅是arr),那么Numba是你的朋友:

import numba as nb


@nb.jit
def count_nb(arr, value):
    result = 0
    for x in arr:
        if x == value:
            result += 1
    return result

或者,对于非常大的数组,并行化可能是有益的:

@nb.jit(parallel=True)
def count_nbp(arr, value):
    result = 0
    for i in nb.prange(arr.size):
        if arr[i] == value:
            result += 1
    return result

可以对np.count_nonzero()(它也有创建临时数组的问题——这是Numba解决方案中避免的问题)和基于np.unique()的解决方案(与其他解决方案相反,它实际上计算所有唯一值值)进行基准测试。

import numpy as np


def count_np(arr, value):
    return np.count_nonzero(arr == value)
import numpy as np


def count_np_uniq(arr, value):
    uniques, counts = np.unique(a, return_counts=True)
    counter = dict(zip(uniques, counts))
    return counter[value] if value in counter else 0 

由于Numba支持“类型化”字典,也可以使用一个函数来计数所有元素的所有出现次数。 这更直接地与np.unique()竞争,因为它能够在一次运行中计算所有值。这里提出了一个最终只返回单个值的元素数量的版本(为了比较,类似于count_np_uniq()中所做的事情):

@nb.jit
def count_nb_dict(arr, value):
    counter = {arr[0]: 1}
    for x in arr:
        if x not in counter:
            counter[x] = 1
        else:
            counter[x] += 1
    return counter[value] if value in counter else 0

输入是通过以下方式生成的:

def gen_input(n, a=0, b=100):
    return np.random.randint(a, b, n)

时间报告在下面的图中(第二行图是对更快的方法的放大):

表明简单的基于numba的解决方案对于较小的输入是最快的,而并行版本对于较大的输入是最快的。 NumPy版本在所有规模上都相当快。

当需要计算数组中的所有值时,对于足够大的数组,np.unique()比手动使用Numba实现的解决方案性能更好。

编辑:在最近的版本中,NumPy解决方案似乎变得更快了。在以前的迭代中,简单的Numba解决方案对于任何输入大小都优于NumPy的方法。


完整的代码可以在这里找到。