问题
I have a list of values and a list of bin edges. Now I need to check for all values to what bin they belong to. Is there a more pythonic way than iterating over the values and then over the bins and checking if the value belongs to the current bin, like:
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
This doesn't look very pretty to me. Thanks!
回答1:
Probably too late, but for future reference, numpy has a function that does just that:
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])
The result is an array of indexes corresponding to the bin from bins that each element from my_list belongs too. Note that the function will also bin values that fall outside of your first and last bin edges:
>>> my_list = [-5,200]
>>> np.digitize(my_list,bins)
array([0, 6])
And Pandas has something like it too:
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:
First of all, your code is going to fail on cases when the value is equal to a bin boundary --
change
if bins(j) < i < bins(j+1):
to have an <=
sign somewhere.
After that, use the bisect
module
import bisect
bisect.bisect(x, bins)
or
bisect.bisect_right
depending on whether you'd prefer to take the higher or lower bin when a value is on the bin boundary.
回答3:
Maybe this will help get you on the right track:
>>> 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]
来源:https://stackoverflow.com/questions/14947909/python-checking-to-which-bin-a-value-belongs