如何在ndarray中计算特定项的出现次数?

625

如何统计以下数组中数字0和1的数量?

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

y.count(0) 的输出为:

numpy.ndarray 对象没有 count 属性。


4
在这种情况下,也可以简单地使用 numpy.count_nonzero 函数。 - Mong H. Ng
32个回答

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

之间的加速非常惊人!


它与直方图相比如何? - john k
@johnktejik np.histogram 不会计算相同的内容。很抱歉,无法将我提出的三种方法与 histogram 函数进行比较。 - Næreen
3
bincount 只适用于整数,因此它适用于提问者的问题,但可能不适用于标题中描述的通用问题。另外,您尝试过在具有非常大整数的数组上使用 bincount 吗? - Imperishable Night
@ImperishableNight 不,我没有尝试过使用大整数,但任何人都可以这样做并发布自己的基准测试结果 :-) - Næreen
谢谢您分享这个被低估的技巧!在我的电脑上,“bincount”比“unique”快四倍。 - Björn Lindqvist
我试过一个形状为(74402,)的数组,使用unique方法需要5.84毫秒±33.6微秒每次循环;而使用bincount方法只需要231微秒±16.3微秒。另外,就像@ImperishableNight提到的一样,使用bincount方法时需要添加.astype(int) - CN_Cabbage

8

要计算出现次数,您可以使用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

7

我会使用np.where:

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

7

y.tolist().count(val)

当val为0或1时,使用Python列表自带的count函数,将y转换为列表后再使用该函数是一种简单的解决方案。


7

试试这个:

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

6

另一个简单的解决方案可能是使用 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

不要被名称所误导,如果像示例中一样与布尔值一起使用,它就能做到。


6

利用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

4
你可以使用字典解析来创建简洁的一行代码。有关字典解析的更多信息,请点击此处
>>> counts = {int(value): list(y).count(value) for value in set(y)}
>>> print(counts)
{0: 8, 1: 4}

这将创建一个字典,以您的ndarray中的值作为键,并将该值在数组中出现次数作为相应的值。

每当您想要计算此格式的数组中值的出现次数时,都可以使用此方法。


3
你有一个仅包含1和0的特殊数组。一个技巧是使用:
np.mean(x)

该函数为您提供数组中数字1的百分比。或者,使用

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

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


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

这里只是复制了Seppo Enarvi的评论,他的评论值得成为一个合适的答案


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接