Qual é a diferença entre pandas.qcut e pandas.cut?

94

A documentação diz:

http://pandas.pydata.org/pandas-docs/dev/basics.html

"Valores contínuos podem ser discretizados usando as funções cut (bins baseados em valores) e qcut (bins baseados em quantis de amostra)"

Parece muito abstrato para mim ... posso ver as diferenças no exemplo abaixo, mas o que qcut (quantil de amostra) realmente significa / significa? Quando você usaria qcut versus cut?

Obrigado.

factors = np.random.randn(30)

In [11]:
pd.cut(factors, 5)
Out[11]:
[(-0.411, 0.575], (-0.411, 0.575], (-0.411, 0.575], (-0.411, 0.575], (0.575, 1.561], ..., (-0.411, 0.575], (-1.397, -0.411], (0.575, 1.561], (-2.388, -1.397], (-0.411, 0.575]]
Length: 30
Categories (5, object): [(-2.388, -1.397] < (-1.397, -0.411] < (-0.411, 0.575] < (0.575, 1.561] < (1.561, 2.547]]

In [14]:
pd.qcut(factors, 5)
Out[14]:
[(-0.348, 0.0899], (-0.348, 0.0899], (0.0899, 1.19], (0.0899, 1.19], (0.0899, 1.19], ..., (0.0899, 1.19], (-1.137, -0.348], (1.19, 2.547], [-2.383, -1.137], (-0.348, 0.0899]]
Length: 30
Categories (5, object): [[-2.383, -1.137] < (-1.137, -0.348] < (-0.348, 0.0899] < (0.0899, 1.19] < (1.19, 2.547]]`
WillZ
fonte

Respostas:

213

Para começar, observe que quantis é apenas o termo mais geral para coisas como percentis, quartis e medianas. Você especificou cinco caixas em seu exemplo, então está pedindo qcutquintis.

Portanto, quando você solicitar quintis com qcut, as caixas serão escolhidas de forma que você tenha o mesmo número de registros em cada caixa. Você tem 30 registros, então deve ter 6 em cada compartimento (sua saída deve ser assim, embora os pontos de interrupção sejam diferentes devido ao sorteio aleatório):

pd.qcut(factors, 5).value_counts()

[-2.578, -0.829]    6
(-0.829, -0.36]     6
(-0.36, 0.366]      6
(0.366, 0.868]      6
(0.868, 2.617]      6

Por outro lado, cutvocê verá algo mais desigual:

pd.cut(factors, 5).value_counts()

(-2.583, -1.539]    5
(-1.539, -0.5]      5
(-0.5, 0.539]       9
(0.539, 1.578]      9
(1.578, 2.617]      2

Isso porque cutescolherá os bins para serem espaçados uniformemente de acordo com os próprios valores e não a frequência desses valores. Conseqüentemente, como você tirou de uma normal aleatória, você verá frequências mais altas nas caixas internas e menos nas externas. Esta será essencialmente uma forma tabular de um histograma (que você esperaria ter em forma de sino com 30 registros).

JohnE
fonte
Ótima resposta para o que é. Você poderia explicar por que escolheria um em vez do outro?
James Hulse
4
@JamesHulse é uma pergunta justa, mas não tenho uma resposta geral. depende apenas se você está procurando uma medida absoluta versus uma medida relativa (quantil) mais do que qualquer outra coisa. Considere a altura, por exemplo: você pode estar interessado na altura relativa (mais de 6 pés de altura) e usar cutou pode se preocupar mais com os 5% mais altos e usarqcut
JohnE
15
  • O comando cut cria caixas equidistantes, mas a frequência das amostras é desigual em cada caixa
  • O comando qcut cria caixas de tamanhos desiguais, mas a frequência das amostras é igual em cada caixa.

insira a descrição da imagem aqui

    >>> x=np.array([24,  7,  2, 25, 22, 29])
    >>> x
    array([24,  7,  2, 25, 22, 29])

    >>> pd.cut(x,3).value_counts() #Bins size has equal interval of 9
    (2, 11.0]        2
    (11.0, 20.0]     0
    (20.0, 29.0]     4

    >>> pd.qcut(x,3).value_counts() #Equal frequecy of 2 in each bins
    (1.999, 17.0]     2
    (17.0, 24.333]    2
    (24.333, 29.0]    2
Ashish Anand
fonte
1
x, bins = pd.cut (list_of_values, bins = 10, labels = list (range (10,0, -1)), retbins = True) Isso é útil para obter bins
Dev_Man
9

Portanto, o qcut garante uma distribuição mais uniforme dos valores em cada compartimento, mesmo se eles se agruparem no espaço amostral. Isso significa que é menos provável que você tenha um compartimento cheio de dados com valores muito próximos e outro compartimento com 0 valores. Em geral, é uma amostragem melhor.

Mir H.
fonte
-1

Pd.qcut distribui os elementos de um array ao fazer a divisão com base em ((no.of elementos no array) / (no. De bins - 1)), então divida este tanto no. de elementos em série em cada caixa.

Pd.cut distribui os elementos de um array ao fazer a divisão com base em ((primeiro + último elemento) / (no. De bins-1)) e, em seguida, distribui o elemento de acordo com a faixa de valores em que eles caem.

Aditya Anand
fonte