Como funciona numpy.histogram ()?

120

Ao ler no numpy, encontrei a função numpy.histogram() .

Para que serve e como funciona? Nos documentos eles mencionam caixas : O que são?

Algumas pesquisas no Google me levaram à definição de histogramas em geral . Entendi. Mas, infelizmente, não posso vincular esse conhecimento aos exemplos fornecidos nos documentos.

Aufwind
fonte

Respostas:

167

Um bin é o intervalo que representa a largura de uma única barra do histograma ao longo do eixo X. Você também pode chamar isso de intervalo. (A Wikipedia os define mais formalmente como "categorias disjuntas".)

A histogramfunção Numpy não desenha o histograma, mas calcula as ocorrências de dados de entrada que caem dentro de cada compartimento, que por sua vez determina a área (não necessariamente a altura se os compartimentos não forem de largura igual) de cada barra.

Neste exemplo:

 np.histogram([1, 2, 1], bins=[0, 1, 2, 3])

Existem 3 bins, para valores que variam de 0 a 1 (excl. 1.), 1 a 2 (excl. 2) e 2 a 3 (incl. 3), respectivamente. A forma como Numpy define esses bins é dando uma lista de delimitadores ( [0, 1, 2, 3]) neste exemplo, embora também retorne os bins nos resultados, já que pode escolhê-los automaticamente na entrada, se nenhum for especificado. E sebins=5 , por exemplo, ele usar 5 caixas de largura igual, espalhadas entre o valor de entrada mínimo e o valor de entrada máximo.

Os valores de entrada são 1, 2 e 1. Portanto, bin "1 a 2" contém duas ocorrências (os dois 1valores) e bin "2 a 3" contém uma ocorrência (o 2). Estes resultados são no primeiro item na tupla retornada: array([0, 2, 1]).

Uma vez que as caixas aqui são de largura igual, você pode usar o número de ocorrências para a altura de cada barra. Quando desenhado, você teria:

  • uma barra de altura 0 para intervalo / bin [0,1] no eixo X,
  • uma barra de altura 2 para intervalo / bin [1,2],
  • uma barra de altura 1 para range / bin [2,3].

Você pode plotar isso diretamente com Matplotlib (sua histfunção também retorna os bins e os valores):

>>> import matplotlib.pyplot as plt
>>> plt.hist([1, 2, 1], bins=[0, 1, 2, 3])
(array([0, 2, 1]), array([0, 1, 2, 3]), <a list of 3 Patch objects>)
>>> plt.show()

insira a descrição da imagem aqui

Bruno
fonte
8
Você também pode estar interessado nesta resposta se quiser traçá-los. Matplotlib também pode calculá-los diretamente . Veja exemplos aqui e aqui .
Bruno
No conjunto de dados de flores de íris, contagens, bin_edges = np.histogram (iris_setosa ['petal_length'], bins = 10, densidade = True) me dá minhas contagens em valores flutuantes, de acordo com o exemplo que você deu como pode contar pode ser um valor flutuante?
Dipen Gajjar
A melhor resposta deve levar em consideração que um número significativo de valores acima da maior borda direita seria ignorado. Sempre adicione valores acima da borda da grade para o último compartimento ou altere o último binsvalor criado manualmente para o valor máximo na matriz.
A.Ametov
@DipenGajjar Se você omitir "densidade = True", não verá isso. A palavra-chave densidade fornece um histograma "normalizado" no qual a função de densidade de probabilidade é representada. Você pode ler sobre isso aqui .
BUFU
67
import numpy as np    
hist, bin_edges = np.histogram([1, 1, 2, 2, 2, 2, 3], bins = range(5))

Abaixo, histindica que há 0 itens no compartimento nº 0, 2 no compartimento nº 1, 4 no compartimento nº 3, 1 no compartimento nº 4.

print(hist)
# array([0, 2, 4, 1])   

bin_edges indica que bin # 0 é o intervalo [0,1), bin # 1 é [1,2), ..., bin # 3 é [3,4).

print (bin_edges)
# array([0, 1, 2, 3, 4]))  

Brinque com o código acima, altere a entrada para np.histograme veja como funciona.


Mas uma imagem vale mais que mil palavras:

import matplotlib.pyplot as plt
plt.bar(bin_edges[:-1], hist, width = 1)
plt.xlim(min(bin_edges), max(bin_edges))
plt.show()   

insira a descrição da imagem aqui

unutbu
fonte
4
Eu acho que isso seria mais preciso: plt.bar(bin_edges[:-1], hist, width=1)e plt.xlim(min(bin_edges), max(bin_edges)), para fazer as barras se ajustarem à largura esperada (caso contrário, pode haver apenas um compartimento menor sem nenhum valor entre eles).
Bruno
É possível usar o "hist" obtido no formato numpy acima na função "plt.hist (...)"? Porque no método bar, você fornece um "y", enquanto aqui no hist, há apenas x ..
kbg
7

Outra coisa útil para fazer numpy.histogramé plotar a saída como as coordenadas xey em um gráfico de linha. Por exemplo:

arr = np.random.randint(1, 51, 500)
y, x = np.histogram(arr, bins=np.arange(51))
fig, ax = plt.subplots()
ax.plot(x[:-1], y)
fig.show()

insira a descrição da imagem aqui

Essa pode ser uma maneira útil de visualizar histogramas em que você deseja um nível mais alto de granularidade sem barras em todos os lugares. Muito útil em histogramas de imagem para identificar valores extremos de pixels.

Grr
fonte
Isso é muito útil para ver as projeções de linha e coluna da imagem.
SKR