2013-12-22 5 views
6

Предположим, у меня была серия значений доллара в долларах США и вы хотели дискретироваться на 9 групп, используя qcut. Число наблюдений не делится на 9. Функция SQL Server ntile имеет стандартный подход для этого случая: он делает первый n из 9 групп. 1 наблюдение больше, чем остальные (9-n) групп.Python Pandas qcut поведение с # наблюдениями, не делящимися на количество ящиков

я заметил в панд, что назначение которых группы имели х наблюдения против х + 1 наблюдения казалось случайным. Я попытался расшифровать код в algos, чтобы выяснить, как функция квантиля справляется с этой проблемой, но не могла понять это.

У меня есть три взаимосвязанных вопроса:

  1. Любые панды разработчиков там, чем можно объяснить поведение qcut «s? Является ли случайным, какие группы получают большее количество наблюдений?
  2. Есть ли способ заставить qcut вести себя аналогично NTILE (то есть, первые группы получают x + 1 наблюдение)?
  3. Если ответ на # 2 нет, любые идеи относительно функции, которая будет вести себя как NTILE? (Если это сложная задача, будет полезно использовать схему вашего подхода.)

Ниже приведен пример вывода SQL Server NTILE.

Bin |# Observations 
1 26 
2 26 
3 26 
4 26 
5 26 
6 26 
7 26 
8 25 
9 25 

Вот панды:

Bin |# Observations 
1 26 
2 26 
3 26 
4 25 (Why is this 25 vs others?) 
5 26 
6 26 
7 25 (Why is this 25 vs others?) 
8 26 
9 26 
+0

Какой ввод дает этот результат? Можете ли вы поделиться своим кодом серии и панды? –

ответ

2

В qcut ведет себя, как это, потому что это более точно. Ниже приведен пример:

для го уровня я, она начинается в квантиль (я -1) * 10%:

import pandas as pd 
import numpy as np 

a = np.random.rand(26*10+3) 
r = pd.qcut(a, 10) 
np.bincount(r.labels) 

выход:

array([27, 26, 26, 26, 27, 26, 26, 26, 26, 27]) 

Если вы хотите использовать NTILE, вы можете сами рассчитать количественные показатели:

n = len(a) 
ngroup = 10 

counts = np.ones(ngroup, int)*(n//ngroup) 
counts[:n%ngroup] += 1 

q = np.r_[0, np.cumsum(counts/float(n))] 
q[-1] = 1.0 
r2 = pd.qcut(a, q) 
np.bincount(r2.labels) 

выход:

array([27, 27, 27, 26, 26, 26, 26, 26, 26, 26]) 
+0

думаю я понимаю. будет ли первый уровень всегда иметь большее количество наблюдений с qcut (поскольку (i-1) не имеет смысла для первого уровня)? также, что необходимо для q [-1] = 1, состоит в том, чтобы гарантировать, что диапазон заканчивается на 1 вместо доли, произвольно близкой к 1? – AllenQ