2016-11-23 53 views
1

這裏是我的數據框:熊貓 - 指定直方圖桶每一行

import pandas as pd 
df = pd.DataFrame({'A': [1, 2, 3, 4, 6, 4, 3, 2, 7]}) 
buckets = [(0,3),(3,5),(5,9)] 

我也有直方圖桶如上所述。現在我想分配數據幀的每一行到桶索引。所以我想用下面的方式來獲得新的列:

df['buckets_index'] = [0,0,0,1,2,1,0,0,2] 

當然,我可以循環做到這一點,但我有相當大的數據框(2.5萬行),所以我需要把它迅速完成。

有什麼想法?

+0

請問水桶限制是這樣的,以前的剷鬥末端將與往常一樣下一個開始? – Divakar

+0

@Divakar,謝謝你的好問題。間隔從左側開放,從右側開放'(0,3],(3,5],(5,9)',是的限制是常見的。 – user1700890

+0

'df.A'中是否有任何元素可以贏得't在任何存儲桶中,即在存儲桶限制之外嗎? – Divakar

回答

2

您可以使用pd.cutlabels=False如果只想索引:

buckets = [0,3,5,9] 
df['bucket'] = pd.cut(df['A'], bins=buckets) 
df['bucket_idx'] = pd.cut(df['A'], bins=buckets, labels=False) 

輸出結果:

A bucket bucket_idx 
0 1 (0, 3]   0 
1 2 (0, 3]   0 
2 3 (0, 3]   0 
3 4 (3, 5]   1 
4 6 (5, 9]   2 
5 4 (3, 5]   1 
6 3 (0, 3]   0 
7 2 (0, 3]   0 
8 7 (5, 9]   2 
+0

如果需要的話,你可以添加'.cat.codes'來獲取整數,而不是類別dtype – jeremycg

1

你可以使用np.searchsorted -

df['buckets_index'] = np.asarray(buckets)[:,1].searchsorted(df.A.values) 

運行測試 -

In [522]: df = pd.DataFrame({'A': np.random.randint(1,8,(10000))}) 

In [523]: buckets = [0,3,5,9] 

In [524]: %timeit pd.cut(df['A'], bins=buckets, labels=False) 
1000 loops, best of 3: 460 µs per loop # @root's soln 

In [525]: buckets = [(0,3),(3,5),(5,9)] 

In [526]: %timeit np.asarray(buckets)[:,1].searchsorted(df.A.values) 
10000 loops, best of 3: 166 µs per loop 

超出限制的情況下:對於這種情況,我們需要使用裁剪,像這樣 -

np.asarray(buckets)[:,1].searchsorted(df.A.values).clip(max=len(buckets)-1) 
+0

我對你和root的解決方案都印象深刻,我希望我能把你的答案都算作正確的答案,我會給出答案,因爲他的排名較低。你不介意 – user1700890

+0

@ user1700890當然,這很好!:) – Divakar