如何计算 ndarray 中某个项目的出现次数?

2025-02-05 13:23:00
admin
原创
59
摘要:问题描述:如何计算以下数组中0s 和s 的数量?1y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]) y.count(0)给出:numpy.ndarray对象没有属性count解决方案 1:使用numpy.unique:import numpy a = num...

问题描述:

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

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

y.count(0)给出:

numpy.ndarray对象没有属性count


解决方案 1:

使用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}

非numpy方法使用collections.Counter

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})

解决方案 2:

那如何使用numpy.count_nonzero,比如

>>> import numpy as np
>>> y = np.array([1, 2, 2, 2, 2, 0, 2, 3, 3, 3, 0, 0, 2, 2, 0])

>>> np.count_nonzero(y == 1)
1
>>> np.count_nonzero(y == 2)
7
>>> np.count_nonzero(y == 3)
3

解决方案 3:

(y == 0).sum()就我个人而言,我会选择:
(y == 1).sum()

例如

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
num_zeros = (y == 0).sum()
num_ones = (y == 1).sum()

解决方案 4:

对于你的情况,你也可以研究numpy.bincount

In [56]: a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

In [57]: np.bincount(a)
Out[57]: array([8, 4])  #count of zeros is at index 0, i.e. 8
                        #count of ones is at index 1, i.e. 4

解决方案 5:

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而不是零(但可能是 2 或 3):

np.count_nonzero(y)

给出非零的数量。

但如果你需要更复杂的东西,我认为 numpy 不会提供一个很好的count选择。在这种情况下,请转到 collections:

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

这就像一个字典

collections.Counter(y)[0]
> 8

解决方案 6:

将数组转换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 

解决方案 7:

如果您确切知道要查找的数字,则可以使用以下命令;

lst = np.array([1,1,2,3,3,6,6,6,3,2,1])
(lst == 2).sum()

返回数组中 2 出现的次数。

解决方案 8:

过滤并使用len

使用len可能是另一种选择。

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

假设我们想知道 出现的次数0

A[A==0]  # Return the array where item is 0, array([0, 0, 0])

现在,用 将其包裹起来len

len(A[A==0])  # 3
len(A[A==1])  # 4
len(A[A==7])  # 0, because there isn't such item.

解决方案 9:

老实说,我发现最简单的方法是转换为 Pandas Series 或 DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({'data':np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])})
print df['data'].value_counts()

或者罗伯特·穆尔 (Robert Muil) 建议的这句精彩俏皮话:

pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts()

解决方案 10:

如果您对最快的执行感兴趣,您事先知道要查找哪些值,并且您的数组是 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)

下图报告了时间安排(第二行图是更快方法的放大图):

完整
bm_缩放

结果表明,基于 Numba 的简单解决方案对于较小的输入速度最快,而并行版本对于较大的输入速度最快。NumPy 版本在所有规模下都相当快。

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

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


完整代码可在此处获取。

解决方案 11:

没有人建议使用numpy.bincount(input, minlength)minlength = np.size(input)但它似乎是一个很好的解决方案,而且绝对是最快的

In [1]: choices = np.random.randint(0, 100, 10000)

In [2]: %timeit [ np.sum(choices == k) for k in range(min(choices), max(choices)+1) ]
100 loops, best of 3: 2.67 ms per loop

In [3]: %timeit np.unique(choices, return_counts=True)
1000 loops, best of 3: 388 µs per loop

In [4]: %timeit np.bincount(choices, minlength=np.size(choices))
100000 loops, best of 3: 16.3 µs per loop

numpy.unique(x, return_counts=True)这是和之间的疯狂加速numpy.bincount(x, minlength=np.max(x))

解决方案 12:

要计算出现的次数,您可以使用np.unique(array, return_counts=True)

In [75]: boo = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
 
# use bool value `True` or equivalently `1`
In [77]: uniq, cnts = np.unique(boo, return_counts=1)
In [81]: uniq
Out[81]: array([0, 1])   #unique elements in input array are: 0, 1

In [82]: cnts
Out[82]: array([8, 4])   # 0 occurs 8 times, 1 occurs 4 times

解决方案 13:

我会使用 np.where:

how_many_0 = len(np.where(a==0.)[0])
how_many_1 = len(np.where(a==1.)[0])

解决方案 14:

y.tolist().count(val)

值为 0 或 1

由于 python 列表具有本机函数count,因此在使用该函数之前转换为列表是一个简单的解决方案。

解决方案 15:

尝试一下:

a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
list(a).count(1)

解决方案 16:

另一个简单的解决方案可能是使用numpy.count_nonzero()

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
y_nonzero_num = np.count_nonzero(y==1)
y_zero_num = np.count_nonzero(y==0)
y_nonzero_num
4
y_zero_num
8

不要让名字误导您,如果您像示例中那样将它与布尔值一起使用,它就会起作用。

解决方案 17:

利用 Series 提供的方法:

>>> import pandas as pd
>>> y = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
>>> pd.Series(y).value_counts()
0    8
1    4
dtype: int64

解决方案 18:

您可以使用字典理解来创建一个简洁的单行代码。有关字典理解的更多信息,请参见此处

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

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

无论何时您想要计算此格式的数组中某个值的出现次数,此方法都会有效。

解决方案 19:

这里有一个只有 1 和 0 的特殊数组。因此,一个技巧是使用

np.mean(x)

这会返回数组中 1 的百分比。或者,使用

np.sum(x)
np.sum(1-x)

将为您提供数组中 1 和 0 的绝对数量。

解决方案 20:

dict(zip(*numpy.unique(y, return_counts=True)))

刚刚复制了 Seppo Enarvi 的评论,这应该是一个正确的答案

解决方案 21:

它涉及到一个步骤,但更灵活的解决方案也适用于二维数组和更复杂的过滤器,即创建一个布尔掩码,然后在掩码上使用 .sum()。

>>>>y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>>>mask = y == 0
>>>>mask.sum()
8

解决方案 22:

一个普遍而简单的答案是:

numpy.sum(MyArray==x)   # sum of a binary list of the occurence of x (=0 or 1) in MyArray

这将导致以下完整代码作为示例

import numpy
MyArray=numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])  # array we want to search in
x=0   # the value I want to count (can be iterator, in a list, etc.)
numpy.sum(MyArray==0)   # sum of a binary list of the occurence of x in MyArray

现在,如果 MyArray 是多维的,并且您想要计算线中值分布的出现次数(以下称为模式)

MyArray=numpy.array([[6, 1],[4, 5],[0, 7],[5, 1],[2, 5],[1, 2],[3, 2],[0, 2],[2, 5],[5, 1],[3, 0]])
x=numpy.array([5,1])   # the value I want to count (can be iterator, in a list, etc.)
temp = numpy.ascontiguousarray(MyArray).view(numpy.dtype((numpy.void, MyArray.dtype.itemsize * MyArray.shape[1])))  # convert the 2d-array into an array of analyzable patterns
xt=numpy.ascontiguousarray(x).view(numpy.dtype((numpy.void, x.dtype.itemsize * x.shape[0])))  # convert what you search into one analyzable pattern
numpy.sum(temp==xt)  # count of the searched pattern in the list of patterns

解决方案 23:

对于通用条目:

x = np.array([11, 2, 3, 5, 3, 2, 16, 10, 10, 3, 11, 4, 5, 16, 3, 11, 4])
n = {i:len([j for j in np.where(x==i)[0]]) for i in set(x)}
ix = {i:[j for j in np.where(x==i)[0]] for i in set(x)}

将输出一个计数:

{2: 2, 3: 4, 4: 2, 5: 2, 10: 2, 11: 3, 16: 2}

和索引:

{2: [1, 5],
3: [2, 4, 9, 14],
4: [11, 16],
5: [3, 12],
10: [7, 8],
11: [0, 10, 15],
16: [6, 13]}

解决方案 24:

可以通过以下方法轻松完成

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

解决方案 25:

由于您的 ndarray 仅包含 0 和 1,因此您可以使用 sum() 获取 1 的出现次数,并使用 len()-sum() 获取 0 的出现次数。

num_of_ones = sum(array)
num_of_zeros = len(array)-sum(array)

解决方案 26:

如果您要处理非常大的数组,使用生成器可能是一个选择。这里的好处是,这种方法对数组和列表都适用,并且您不需要任何额外的包。此外,您不会使用那么多内存。

my_array = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
sum(1 for val in my_array if val==0)
Out: 8

解决方案 27:

此函数返回数组中变量出现的次数:

def count(array,variable):
    number = 0
    for i in range(array.shape[0]):
        for j in range(array.shape[1]):
            if array[i,j] == variable:
                number += 1
    return number

解决方案 28:

这里有一些东西,你可以通过它来计算特定数字出现的次数:根据你的代码

count_of_zero=list(y[y==0]).count(0) 

print(count_of_zero)

// according to the match there will be boolean values and according
// to True value the number 0 will be return.

解决方案 29:

如果您不想使用 numpy 或 collections 模块,您可以使用字典:

d = dict()
a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
for item in a:
    try:
        d[item]+=1
    except KeyError:
        d[item]=1

结果:

>>>d
{0: 8, 1: 4}

当然你也可以使用 if/else 语句。我认为 Counter 函数的作用几乎相同,但这个更透明。

解决方案 30:

最简单的,如果不需要就注释掉

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
count_0, count_1 = 0, 0
for i in y_train:
    if i == 0:
        count_0 += 1
    if i == 1:
        count_1 += 1
count_0, count_1
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用