不使用 bin 间隔但使用具体值的直方图

Histogram which do not use bin intervals but concrete values

我破解了下面的代码,它基本上是不使用间隔 bin 的直方图。它对离散值很有用。我用纯 numpy 完成了它:

In [281]: a = np.array([1,2,5,3,2])

In [282]: hist, bin_edges = np.histogram(a, bins = np.arange(np.amin(a), np.amax(a) + 2))

In [283]: freq = hist

In [284]: nums = bin_edges[1:] - 1

In [285]: matrix = np.transpose((nums, freq))

In [286]: matrix[matrix[:,1]!=0]
Out[286]:
array([[1, 1],
       [2, 2],
       [3, 1],
       [5, 1]])

问题:

  1. 有没有比我的代码更简单高效的方法?
  2. 如何对十进制值进行同样的操作?我想整个技巧都在 np.arrange 函数中。基本上我需要直方图,它不会使用间隔而是使用具体值,例如以下输入:

    1.2, 2.3, 2.4, 2, 5, 8, 9, 2.3, 1.2

应该return以下输出:

[1.2, 2],
[2, 1],
[2.3, 2],
[2.4, 1],
[5, 1],
[8, 1],
[9, 1],

对于整数数组,您可以使用 numpy.bincount

例如,

In [59]: a = np.array([1,2,5,3,2])

In [60]: np.bincount(a)
Out[60]: array([0, 1, 2, 1, 0, 1])

return 值是从 0 到输入中找到的最大值的值计数数组。

对于浮点值数组,您可以使用 numpy.unique 和参数 return_counts=True(如果您使用的是 numpy 1.9 或更高版本)。

例如,

In [64]: b = [1.2, 2.3, 2.4, 2, 5, 8, 9, 2.3, 1.2]

In [65]: values, counts = np.unique(b, return_counts=True)

In [66]: values
Out[66]: array([ 1.2,  2. ,  2.3,  2.4,  5. ,  8. ,  9. ])

In [67]: counts
Out[67]: array([2, 1, 2, 1, 1, 1, 1])

但是请注意,这使用了浮点值的相等比较,由于正常的浮点不精确,这可能会导致一些令人惊讶的结果:

In [98]: c = [0.1+0.2, 0.3]

In [99]: np.unique(c, return_counts=True)
Out[99]: (array([ 0.3,  0.3]), array([1, 1]))

查看c看看发生了什么:

In [100]: c
Out[100]: [0.30000000000000004, 0.3]

您可以使用 collections.Counter:

>>> from collections import Counter
>>> counter = Counter([1,2,5,3,2])
>>> counter[1]
1

同样,

>>> counter = Counter([1.2, 2.3, 2.4, 2, 5, 8, 9, 2.3, 1.2])
>>> counter[1.2]
2

使用 Counter.items() 获取键值对:

>>> counter.items()
[(2, 1), (5, 1), (8, 1), (2.4, 1), (1.2, 2), (9, 1), (2.3, 2)]

如果出于某种原因你想将它们更改为列表列表而不是元组列表:

>>> map(list, counter.items())
[[2, 1], [5, 1], [8, 1], [2.4, 1], [1.2, 2], [9, 1], [2.3, 2]]