我如何计算一个ndarray中某一项的出现?

我如何计算以下数组中# eyz0和# eyz1的数量?

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

# EYZ0给:

numpy.ndarray对象没有count属性

946796 次浏览

使用# EYZ1:

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}

Non-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})
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

如果你知道它们是01:

np.sum(y)

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

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

np.count_nonzero(y)

给出非零的个数。

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

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

对于您的情况,您还可以查看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

我会使用np.where:

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

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

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

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

筛选并使用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.
就我个人而言,我倾向于: (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()

# EYZ0

val为0或1

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

如果你不想使用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函数做了几乎相同的事情,但这个更透明。< / p >

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

不要让这个名字误导了你,如果你像例子中那样使用布尔值,它会达到目的的。

这可以用下面的方法轻松完成

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

老实说,我发现最容易转换为熊猫系列或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()

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

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在多个维度中,并且你想要计数值在一行(= pattern后)中分布的出现次数。

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

要计算出现的次数,您可以使用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
因为你的ndarray只包含0和1, 您可以使用sum()来获得1的出现次数 和len()-sum()来获取0的出现情况
num_of_ones = sum(array)
num_of_zeros = len(array)-sum(array)

没有人建议使用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))之间有一个疯狂的加速!

Numpy为此提供了一个模块。只是一个小hack。将输入数组作为箱子。

numpy.histogram(y, bins=y)

输出是2个数组。一个是数值本身,另一个是相应的频率。

如果你确切地知道你要找的数字,你可以使用下面的方法;

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

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

对于一般条目:

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

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

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

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

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

你有一个只有1和0的特殊数组。一个技巧就是使用

np.mean(x)

也就是数组中1的百分比。另外,使用

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

会给出数组中1和0的绝对值。

利用a系列提供的方法:

>>> 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
using numpy.count


$ a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]


$ np.count(a, 1)
dict(zip(*numpy.unique(y, return_counts=True)))

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

试试这个:

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

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

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.

如果你对最快的执行感兴趣,你提前知道要查找哪个(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解决方案中是避免的)和基于# eyz1的解决方案(与其他解决方案相反,它实际上是计算所有唯一值的值)进行基准测试。

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

由于支持"typed"在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_full # EYZ0 < / p >

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

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

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


完整代码可用在这里

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

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

这个函数返回变量在数组中出现的次数:

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