2013-02-19 15 views
6

मेरे पास मूल्यों की एक सूची है और बिन किनारों की एक सूची है। अब मुझे सभी मानों की जांच करने की आवश्यकता है कि वे किस बिन से संबंधित हैं।पायथन: यह जांच कर रहा है कि कौन सा बिन एक मान है

my_list = [3,2,56,4,32,4,7,88,4,3,4] 
bins = [0,20,40,60,80,100] 

for i in my_list: 
    for j in range(len(bins)): 
     if bins(j) < i < bins(j+1): 
      DO SOMETHING 

यह मेरे लिए बहुत सुंदर नहीं लगती है: वहाँ मूल्यों पर और फिर डिब्बे से अधिक पुनरावृत्ति और जाँच की तुलना में अधिक pythonic तरीका अगर मूल्य की तरह, वर्तमान बिन के अंतर्गत आता है है। धन्यवाद!

+0

सूची को सॉर्ट करके शुरू करें। –

उत्तर

14

शायद बहुत देर हो चुकी है, लेकिन भविष्य में संदर्भ के लिए, numpy एक समारोह है कि सिर्फ इतना है कि करता है:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

>>> my_list = [3,2,56,4,32,4,7,88,4,3,4] 
>>> bins = [0,20,40,60,80,100] 
>>> np.digitize(my_list,bins) 
array([1, 1, 3, 1, 2, 1, 1, 5, 1, 1, 1]) 

परिणाम से बिन करने के लिए इसी अनुक्रमित की एक सरणी है डिब्बे कि my_list से प्रत्येक तत्व भी संबंधित है। ध्यान दें कि समारोह भी बिन मानों अपना पहला और अंतिम बिन किनारों में शामिल नहीं हैं:

>>> my_list = [-5,200] 
>>> np.digitize(my_list,bins) 
array([0, 6]) 

और पांडा भी यह की तरह कुछ है:

http://pandas.pydata.org/pandas-docs/dev/basics.html#discretization-and-quantiling

>>> pd.cut(my_list, bins) 
Categorical: 
array(['(0, 20]', '(0, 20]', '(40, 60]', '(0, 20]', '(20, 40]', '(0, 20]', 
     '(0, 20]', '(80, 100]', '(0, 20]', '(0, 20]', '(0, 20]'], dtype=object) 
Levels (5): Index(['(0, 20]', '(20, 40]', '(40, 60]', '(60, 80]', 
        '(80, 100]'], dtype=object) 
2

हो सकता है कि इस में मदद मिलेगी सही रास्ते पर आपको मिलता है:

>>> import itertools 
>>> my_list = [3,2,56,4,32,4,7,88,4,3,4] 
>>> for k, g in itertools.groupby(sorted(my_list), lambda x: x // 20 * 20): 
...  print k, list(g) 
... 
0 [2, 3, 3, 4, 4, 4, 4, 7] 
20 [32] 
40 [56] 
80 [88] 
+0

आश्चर्यजनक वोट क्यों आश्चर्य है। – sberry

3

सबसे पहले, अपने कोड मामलों पर विफल जब मूल्य एक बिन सीमा के बराबर है जा रहा है -

परिवर्तन

if bins(j) < i < bins(j+1): 

<= कहीं कहीं साइन इन करें।

उसके बाद, bisect मॉड्यूल

import bisect 
bisect.bisect(x, bins) 

या bisect.bisect_right

आप अधिक या कम बिन लेने के लिए जब एक मूल्य बिन सीमा पर है पसंद करते हैं, इस आधार पर इस्तेमाल करते हैं।

+1

मुझे लगता है कि 'bisect' के तर्कों को उलट दिया गया है। – sberry

संबंधित मुद्दे