2016-07-26 37 views
2

請考慮以下簡單示例。我有興趣獲得包含與分位數相對應的分類的分類變量。如何在數據中存在關聯時計算Pandas中的分位數?

df = pd.DataFrame({'A':'foo foo foo bar bar bar'.split(), 
         'B':[0, 0, 1]*2}) 

df 
Out[67]: 
    A B 
0 foo 0 
1 foo 0 
2 foo 1 
3 bar 0 
4 bar 0 
5 bar 1 

在熊貓,qtile做的工作。不幸的是,qtile由於數據中的關係而會失敗。

df['C'] = df.groupby(['A'])['B'].transform(
        lambda x: pd.qcut(x, 3, labels=range(1,4))) 

給出了經典ValueError: Bin edges must be unique: array([ 0. , 0. , 0.33333333, 1. ])

有另一種強大的解決方案(從任何其他Python包),不需要推倒重來?

它必須是。我不想自己編碼自己的分位數bin函數。任何體面的統計包可以在創建分位箱時處理關係(SASStata等)。

我想有一些基於健全的方法選擇和強大的東西。

例如,在這裏尋找SAS https://support.sas.com/documentation/cdl/en/proc/61895/HTML/default/viewer.htm#a000146840.htm的解決方案。

或在這裏爲Stata(http://www.stata.com/manuals13/dpctile.pdf)着名的xtile。請注意此SO帖子Definitive way to match Stata weighted xtile command using Python?

我錯過了什麼?也許使用Scipy

非常感謝!

回答

3

IIUC,您可以使用numpy.digitize

df['C'] = df.groupby(['A'])['B'].transform(lambda x: np.digitize(x,bins=np.array([0,1,2]))) 

    A B C 
0 foo 0 1 
1 foo 0 1 
2 foo 1 2 
3 bar 0 1 
4 bar 0 1 
5 bar 1 2 
+0

感謝@NickilMaveli但似乎'numpy.digitize'不會產生位數垃圾箱,而是線性間隔箱 –

+1

在這種情況下,你可以通過'PD的輸出.quantile()'方法來'np.digitize'函數。如果存在非唯一值,那麼它將分配與最後一個四分位數相關的整數(這裏是3)。 –

+0

確實很好的建議。不幸的是,我認爲把他們放在最低四分位數更普遍..也許有另一種解決方案.. –